I'm teaching myself Verilog with HDLbits and tackling this problem. According to this post, assignment with the LHS of the expression as a concatenation should work. In practice I've used this many times before. However, when I assign a wire to a concatenation and then use a non-blocking assignment on that wire, the wire is not driven.
module top_module (
input clk,
input reset,
input [3:1] s,
output fr3,
output fr2,
output fr1,
output dfr
);
parameter lowest = 3'b000, aboveS1 = 3'b001, aboveS2 = 3'b011, aboveS3 = 3'b111;
parameter hf = 3'b111, mf = 3'b011, lf = 3'b001, zf = 3'b000;
reg [2:0] state, next_state;
wire [2:0] flowrate = {fr3,fr2,fr1}; //problem area
always @ * begin
next_state = {s[3],s[2],s[1]};
end
always @ (posedge clk) begin
if(reset) begin
state <= lowest;
{fr3,fr2,fr1} <= hf;
dfr <= 1'b1;
end else begin
if(next_state != state)
dfr <= next_state < state;
else
dfr <= dfr;
case(next_state)
aboveS1 : flowrate <= mf; //problem area
aboveS2 : flowrate <= lf;
aboveS3 : flowrate <= zf;
default : flowrate <= hf;
endcase
state <= next_state;
end
end
endmodule
The above code fails as fr3, fr2, and fr1 are stuck at ground. But when the case statement is changed to the following:
aboveS1 : {fr3,fr2,fr1} <= mf;
aboveS2 : {fr3,fr2,fr1} <= lf;
aboveS3 : {fr3,fr2,fr1} <= zf;
default : {fr3,fr2,fr1} <= hf;
The code works fine, and the outputs are driven. Why does this occur?
There is also this warning thrown by Quartus which I'm sure is related:
Warning (10036): Verilog HDL or VHDL warning at top_module.v(13):
object "flowrate" assigned a value but never read File:
/home/h/work/hdlbits.2001977/top_module.v Line: 13
Warning (13024): Output pins are stuck at VCC or GND
Warning (13410): Pin "fr3" is stuck at VCC File:
/home/h/work/hdlbits.2001977/top_module.v Line: 5
Warning (13410): Pin "fr2" is stuck at VCC File:
/home/h/work/hdlbits.2001977/top_module.v Line: 6
Warning (13410): Pin "fr1" is stuck at VCC File:
/home/h/work/hdlbits.2001977/top_module.v Line: 7
The following replacements in the upper area also break:
wire [2:0] flowrate;
assign {fr3,fr2,fr1} = flowrate;
and
wire [2:0] flowrate;
assign flowrate = {fr3,fr2,fr1};
Edit: clarified error a bit more
aliasandletconstructs that both give you the bidirectional semantics you are looking for. \$\endgroup\$