Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
Announcements
Intel Support hours are Monday-Fridays, 8am-5pm PST, except Holidays. Thanks to our community members who provide support during our down time or before we get to your questions. We appreciate you!

Need Forum Guidance? Click here
Search our FPGA Knowledge Articles here.
15540 Discussions

newbie question: synchronous versus combinational bus mux using case statement

Altera_Forum
Honored Contributor II
949 Views

Hello all- 

 

Can anyone explain why the first (synchronous) version below compiles in quartus, but the second (combinational) does not? In the 2nd case the error is: 

 

Error (10137): Verilog HDL Procedural Assignment error at my_first_fpga.v(26): object "LED" on left-hand side of assignment must have a variable data type 

Error (10137): Verilog HDL Procedural Assignment error at my_first_fpga.v(27): object "LED" on left-hand side of assignment must have a variable data type 

 

Is there a proper way to code a combinational bus mux using a case statement? 

 

Thanks 

-J 

 

module my_first_fpga ( input wire CLOCK_50, input wire KEY, output reg LED ); reg count; always @ (posedge CLOCK_50) begin count <= count + 1; case(KEY) 0 : LED = count; 1 : LED = count; endcase end endmodule  

 

module my_first_fpga ( input wire CLOCK_50, input wire KEY, output wire LED ); reg count; always @ (posedge CLOCK_50) begin count <= count + 1; end always @ (KEY, count) case(KEY) 0 : LED = count; 1 : LED = count; endcase endmodule
0 Kudos
7 Replies
Altera_Forum
Honored Contributor II
131 Views

make LED a reg in 2nd code. 

A reg is not automatically a register, it is just a data type. A wire can only be used in an assign statement. reg types can be used in procedural code.
Altera_Forum
Honored Contributor II
130 Views

Or set Verilog HDL input to System Verilog, it will accept wire as assignment target.

Altera_Forum
Honored Contributor II
130 Views

 

--- Quote Start ---  

make LED a reg in 2nd code. 

A reg is not automatically a register, it is just a data type. A wire can only be used in an assign statement. reg types can be used in procedural code. 

--- Quote End ---  

 

 

Hi, thanks for the reply.  

 

So, it sounds like you are suggesting that a reg type can be used to generate combinational logic... say by using it outside of an always @ (posedge) block. I hadn't thought of this, but I'll give it a try and see if it works. 

 

-J
Altera_Forum
Honored Contributor II
131 Views

This is a quirk of Verilog. Reg is just a data type in the Verilog. What it maps to in logic is down to the behaviour in the code. It is just unfortunate they chose the name "reg"

Altera_Forum
Honored Contributor II
131 Views

 

--- Quote Start ---  

This is a quirk of Verilog. Reg is just a data type in the Verilog. What it maps to in logic is down to the behavior in the code. It is just unfortunate they chose the name "reg" 

--- Quote End ---  

 

 

Yes, indeed, sir. I found both the code snippets below generate the desired combinational logic. I would guess the 2nd one might be frowned upon. 

 

Would you be able to recommend a book that covers these sorts of issues? It would be nice to find one that is written in Verilog 2001. 

 

Thanks again, 

-J 

always @ (KEY,count) case(KEY) 0 : LED = count; 1 : LED = count; endcase  

always @ (KEY) case(KEY) 0 : LED = count; 1 : LED = count; endcase
Altera_Forum
Honored Contributor II
131 Views

The second code wont match between simulation and synthesis as you dont have count in the sensitivity list. 

Also, I recommend using non-blocking assignments in always blocks <=
Altera_Forum
Honored Contributor II
131 Views

 

--- Quote Start ---  

The second code wont match between simulation and synthesis as you dont have count in the sensitivity list. 

Also, I recommend using non-blocking assignments in always blocks <= 

--- Quote End ---  

 

 

The first statement I agree with. Not so the second; it depends on what you are trying to accomplish. 

 

If you are trying to model physical registers, than using the non-blocking assignment <= makes sense, as it evaluates the right side, and then assigns the result to the left side based on the event used in the enclosing always block (typically 'posedge clk'). 

 

If you want to model pure combinatorial logic and use 'reg' variables as intermediate holding values, with no intercycle memory, then blocking = assignment makes more sense, as it works within the procedural flow. Example: 

 

begin : label reg tmp; tmp = a; if (b == c) tmp = d; if (e == f) tmp = g; h = tmp; end 

 

produces the same result as: 

 

h = (e == f) ? g : ((b == c) ? d : a); 

 

Of course this is a very contrived example but sometimes it is more clear to write out the combinatorial logic as a multi line procedure rather than to combine the whole thing into a single equation.
Reply