0
\$\begingroup\$

I'm having problem with my verilog code when I synthesize it. It shows multiple drivers error. I think may be it's because of multiple always blocks I'm using in it. So how can I fix it!!? Here it is:

module check(csx,dcx,wrx,rdx,clk,d_out,res);
input wire clk,res;
output reg csx,dcx,wrx,rdx;
output reg [7:0]d_out;
reg [2:0]count;

always @ (res)
begin
  if (res==1)
  begin
    csx=1;
    wrx=0;
    rdx=1;
    dcx=0;
    count=0;
    d_out=0;
  end
end

always @ (posedge clk)
begin
  count=count+1;
end

always @ (count)
begin
  repeat(3'h5)
  begin
    if((count+res)==3'h2)
    begin
      d_out=8'h28;
    end
    else if(count==3'h3)
    begin
      csx=0;
      wrx=1;
    end
    else if (count==3'h4)
    begin
      wrx=0;
      csx=1;
      d_out=8'h11;
    end
    else if (count==3'h5)
    begin
      csx=0;
      wrx=1;
    end
  end
end

endmodule
\$\endgroup\$
2
\$\begingroup\$

You can't add the reset logic as a separate always block; you need to incorporate the reset into the blocks you already have.

Also, you can't use the repeat block that way in synthesizable code. I'm not sure exactly what you're trying to accomplish with it; it looks like you could simply delete that line and the associated end line.

|improve this answer|||||
\$\endgroup\$
0
\$\begingroup\$

To be synthesisable, reg types can only be assigned within one always block. Verilog allows regs to be assigned anywhere for test bench and non-synthesiable modeling purposes.

repeat is a non-synthesiable keyword. Again, it is for test benches and non-synthesiable modeling.

The always @ (count) block is inferring latching logic for two reasons:

  1. The sensitivity list is incomplete. It should be always @ (count or res) or always @*
  2. csx,dcx,wrx,rdx,d_out are not assigned in every branched condition, this infers latches.

Most likely you want to put in one always block and have csx,dcx,wrx,rdx,d_out be flops:

always @(posedge clk or posedge res) // clock edge or async reset
begin
  if (rst == 1'b1) begin // reset
    // assign all regs a constant default value
    csx <= 1'b1; // use non-blocking assignment (<=)
    wrx <= 1'b0; // recommenced to use to use explicit bit-width and radix
    // ...
  end
  else begin
    case (count)
      3'd1: d_out=8'h28;
      3'd2: begin
              csx=0;
              wrx=1;
            end
      // ... other conditions 
    endcase
    count <= count + 1'd1;
  end

If your simulator and synthesizer support SystemVerilog, I'd recommend using the always_ff (for flip-flops), always_comb (for combination logic) and always_latch (for intended latches). They are like the traditional always expect they throw compiling errors if more than one always* block is assigning the same register, if blocking delay elements are found withing the block, and additional checks for synthesisablity. It also give improved guidance to linting and logical equivalency checking tools. It will give the same result as properly coded Verilog.

|improve this answer|||||
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.