Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Altera_Forum
Honored Contributor I
880 Views

newbie question: synchronous versus combinational bus mux using case statement

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 I
62 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 I
62 Views

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

Altera_Forum
Honored Contributor I
62 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 I
62 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 I
62 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 I
62 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 I
62 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