Verilog beginner here. Working with Lattice Diamond for a design using the MachXO2.
For context: I recently got this answer to a related question. See the second image in the answer.
I want to implement a dblbuffer
module that internally has the two FIFOs as shown in that diagram (FIFO_DC module from their IPExpress; module name is fifo_dc
), and externally just has input data / write clock, and output data /read clock (plus some additional auxiliary signals, not relevant to this post/question).
I can't seem to connect the output from the selector/multiplexer to the module's output:
module dblbuffer (data_in, wr_clk, out, rd_clk, save_current);
input wr_clk, rd_clk, save_current;
input [15:0] data_in;
output [15:0] out;
reg selected; // a buffered/synchronized/edge-detection version of save_current
// (details related to it omitted here for simplicity)
always @(fifo0.Q, fifo1.Q, selected)
begin
out[15:0] <= (selected ? fifo1.Q[15:0] : fifo0.Q[15:0]);
end
fifo_dc fifo0
(
.Data(data_in),
.WrClock(wr_clk),
.RdClock(rd_clk),
// ···
.Q(), // Should I leave Q unassigned, to be used as above?
// ···
);
fifo_dc fifo1 ....
The synthesizer gives me procedural assignment to a non-register out is not permitted. VERI-1100
.
So, I try adding:
reg[15:0] out_wires;
assign out_wires[15:0] = out[15:0];
And now it tells me concurrent assignment to a non-net out_wires is not permitted. VERI-1195
. I thought it was related to the =
vs. <=
, but trying that with the <=
gives me a plain syntax error (syntax error near <=. VERI-1137
).
If I simply try reg[15:0] out_wires = out[15:0]
it tells me that out is not a constant. VERI-1188
.
I hope it's clear what I'm trying to do so that someone can point out the correct syntax (or the correct structure, if what I'm doing wrong goes beyond just syntax).
Thanks!
2 Answers 2
It would be simpler to just declare the output port as reg
(instead of the default, which is wire
):
output reg [15:0] out;
But you don't really need the always
block anyway, so just write:
output [15:0] out;
assign out[15:0] = (selected ? fifo1.Q[15:0] : fifo0.Q[15:0]);
-
\$\begingroup\$ Huh -- with
output reg[15:0] out
and the rest unchanged, I get the errordblbuffer.v(22): external reference fifo0.Q remains unresolved. VERI-1172
(line 22 isalways @(fifo0.Q, fifo1.Q, selected)
. Actually with either of the two approaches (with theassign
line it gives me the same error). Perhaps, that reflects some other error that was there, but the non-reg error was making the compiler/synthesizer stop before reaching this fifo0.Q unresolved error? \$\endgroup\$Cal-linux– Cal-linux2019年09月15日 21:01:13 +00:00Commented Sep 15, 2019 at 21:01 -
1\$\begingroup\$ Yes, that's a separate problem. \$\endgroup\$Dave Tweed– Dave Tweed2019年09月15日 21:04:30 +00:00Commented Sep 15, 2019 at 21:04
-
\$\begingroup\$ Sweet -- declaring
wire[15:0] fifo0_Q, fifo1_Q
, changing to(selected ? fifo1_Q ···
and tying the .Q of the module to the wires (as in:.Q(fifo0_Q)
) seems to solve the issue. I guess one day I will understand why! :-) (and hopefully it is the right thing to do) \$\endgroup\$Cal-linux– Cal-linux2019年09月15日 21:20:46 +00:00Commented Sep 15, 2019 at 21:20 -
\$\begingroup\$ @TomCarpenter -- we seem to have had a race condition! I figured out this change and wrote this comment before I saw your answer (but right after I posted it, I saw that your answer was already there! :-) We even chose the same names
fifo0_Q
andfifo1_Q
.... I guess they're sort of an obvious choice) \$\endgroup\$Cal-linux– Cal-linux2019年09月15日 21:32:05 +00:00Commented Sep 15, 2019 at 21:32
Use a wire to connect to the output of the FIFO. You can if you want for example use a 2D array of wires, then indexing with the selected
signal to infer a mux.
output [15:0] out;
wire [15:0] fifo_Q [0:1];
assign out = fifo_Q[selected];
fifo_dc fifo0
...
.Q(fifo_Q[0])
);
...
You could also use the ternary operator (as per @DaveTweed's suggestion) but with a pair of wires connected to the Q outputs:
wire [15:0] fifo0_Q;
wire [15:0] fifo1_Q;
assign out = selected ? fifo1_Q : fifo0_Q;
...
.Q(fifo0_Q)
);
...
-
\$\begingroup\$ "indexing with the
selected
signal to infer a mux" -- aww, that is awesome!!! (I mean, I probably won't change the code, which already had the ternary operator to suggest a mux — although who am I kidding: like I'm going to resist the temptation :-) ) \$\endgroup\$Cal-linux– Cal-linux2019年09月15日 21:26:40 +00:00Commented Sep 15, 2019 at 21:26 -
\$\begingroup\$ "wire [15:0] fifo_Q [0:1];" -- does it make a difference if I write
[1:0]
instead of[0:1]
? I find it curious that you specificallly wrote it like that, but you left the[15:0]
like that, with the opposite ordering. \$\endgroup\$Cal-linux– Cal-linux2019年09月15日 21:46:08 +00:00Commented Sep 15, 2019 at 21:46 -
1\$\begingroup\$ @Cal-linux The index ordering doesn't really matter, its just an odd convention left over from memory address being in ascending order, hence
[0:1]
, but binary being written MSB first, hence[15:0]
. It doesn't matter if you flip the ordering. \$\endgroup\$Tom Carpenter– Tom Carpenter2019年09月16日 07:19:51 +00:00Commented Sep 16, 2019 at 7:19