Question

I'm new to verilog HDL and my first project is to implement a simple stopwatch counter using a set of registers. I'm using Altera Quartus.

When I tried compiling the code below, I keep getting an error for each and everyone of the registers. one of the error messages looks like this:

Error (10028): Can't resolve multiple constant drivers for net "sec0[3]" at test_interface.v(127)

Anyone can help? The code simulates fine in Modelsim.

Here's the fragment of code that's causing problems:

always @ (posedge clk)

  if (qsoutput == 1)
      sec0 = sec0 + 1;
  else if (sec0 == 4'b1010) begin
      sec1 = sec1 + 1;
      sec0 = 4'b0000;
  end else if (sec1 == 4'b0110) begin
      min0 = min0 + 1;
      sec1 = 4'b0000;
  end else if (min0 == 4'b1010) begin
      min1 = min1 + 1;
      min0 = 4'b0000;     
  end else if (min1 == 4'b0110) begin
      sec0 = 4'b0000;
      sec1 = 4'b0000;
      min0 = 4'b0000;
      min1 = 4'b0000;
  end
Was it helpful?

Solution

Based on your code in Dropbox, you are assigning registers in multiple always blocks. This is illegal for synthesis and cosponsors to the Altera Quartus error message is referring to. A reg type should only be assigned with in one always block.

As an example, sec0 is defined in always @(posedge reset_reg) and the code provided in your question. The code in Dropbox is even worse because you split the counter logic into 4 separate always blocks that assign sec0.

I suggest you put all sec* and min* resisters one clock synchronous always block with an asynchronous:

always(@posedge clk or posedge reset_reg)
begin
  if(reset_reg)
  begin
    // ... asynchronous reset code ...
  end
  else
  begin
    // ... synchronous counter code ...
  end
end

This paper goes into detail about good verilog coding practices for synthesis: http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf


Other issues you will have:

  • Use non-blocking (<=) when assigning registers. This is discussed in Cliff's paper mentioned earlier.
  • Get rid of the initial block. I understand some FPGA synthesizers allow it and some ignore it. It is a better practice to have an asynchronous to put everything into a known and predictable value.
  • The block starting with always @ (clk or start_reg or lap_reg or reset_reg) has a bizarre sensitivity list and will likely give you problems. you wither want @(*) if you want combination logic or @(posedge clk or posedge reset_reg) for synchronous flops.
  • Very rarely dual edge flops are used. The line always @ (posedge clk or negedge clk) should be always @ (posedge clk) for synchronous or always @(*) for combination logic.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top