Electronic – Verilog — how to assign mux/selector output to module’s output

fpgalatticeverilog

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!

Best Answer

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]);