Problems assigning to LEDs in a case block [duplicate] - verilog

This question already has an answer here:
Using a continous assignment in a Verilog procedure?
(1 answer)
Closed 10 months ago.
When I enter something like this:
always #* begin
case(SW[17])
1'b0: assign LEDG = SW[7:0];
1'b1: assign LEDG = SW[15:8];
endcase
end
where LEDG is set of [7:0] green LEDs, I get the error:
Error (10137): Verilog HDL Procedural Assignment error at
part2.v(20): object "LEDG" on left-hand side of assignment must have a
variable data type
upon trying to compile. However, when I put a similar assignment statement outside the case block, such as:
assign LEDG = SW[7:0];
it assigns just fine. I can't seem to figure out the issue.

My guess is you have declared LEDG as
wire [7:0] LEDG;
Change it to
reg [7:0] rLEDG;
wire [7:0] LEDG;
assign LEDG = rLEDG;
Your always block should now assign rLEDG.
Basically, always blocks cannot assign to wires, only regs. assign statements on the other hand, assign to wires not regs.

Assign statements can't be used inside an always block. Remove 'assign' from the line and change your 'output [7:0] LEDG' array to 'output reg [7:0] LEDG' . A reg data type must be used inside always blocks.

Using an assign like that you are most likely not doing what you expect. See using-a-continous-assignment-in-a-verilog-procedure for an explanation of what your currently doing.
To expand in DJZygotes answer, LEDG must be a wire for continuous assign or reg for assignment in an always or initial block.
wire [7:0] LEDG;
assign LEDG = SW[7:0];
Or:
reg [7:0] LEDG;
always #* begin
case(SW[17])
1'b0: LEDG = SW[7:0];
1'b1: LEDG = SW[15:8];
endcase
end

Related

I am getting unknown value when doing a 4 bit shifter verilog (gate level)

I am trying to implement a 4 bit right shifter using gate level but i got unknown result for some reason, my mux work ok but when i try testbench for my shifter it give back something like this:
a=0010 b=01 c=0000
a=1111 b=01 c=00xx
Please help!!!! Thank you very much
module mux2(a,b,sel,c);
output c;
input a,b,sel;
wire net0,net1,net2;
not m1(net0,sel);
and m2(net1,a,net0);
and m3(net2,b,sel);
or m4(c,net1,net2);
endmodule
module mux4(a,sel,c);
output c;
input [1:0]sel;
input[3:0]a;
wire mux_1,mux_2;
mux2 m1(a[3],a[2],sel[0],mux_1);
mux2 m2(a[1],a[0],sel[0],mux_2);
mux2 m3(mux_1,mux_2,sel[1],c);
endmodule
module shift4bitright(c,a,b);
output [3:0]c;
input [3:0]a;
input [1:0]b;
wire [3:0]d=4'h0,d1=4'h0,d2=4'h0,d3=4'h0;
assign d[0]=a[3];
assign d1[0]=a[2]; assign d1[1]=a[3];
assign d2[0]=a[1]; assign d2[1]=a[2]; assign d2[2]=a[3];
assign d3[0]=a[0]; assign d3[1]=a[1];assign d3[2]=a[2];assign d3[3]=a[3];
mux4 m1(d,b,c[3]);
mux4 m2(d1,b,c[2]);
mux4 m3(d2,b,c[1]);
mux4 m4(d3,b,c[0]);
endmodule
`timescale 10ns/1ns
module shift4bitright_tb;
wire [3:0]c;
reg [3:0]a;
reg [1:0]b;
shift4bitright s1(.c(c),.a(a),.b(b));
initial begin
$monitor("a=%b b=%b c=%b",a,b,c);
a=4'h2;
b=2'd1;
#50
a=4'hf;
b=2'd1;
end
endmodule
This statement declared a wire type signal d as well as its driver cone (NOT initial value), which is a constant 0 in this case:
wire [3:0]d=4'h0;
Just below it, there's another a[3] driving d[0]:
assign d[0]=a[3];
This creates a multi-driven logic, hence x occurs.
To solve it, change it similar to:
wire [3:0] d;
assign d = {3'h0, a[3]};

Write to a reg's bitfields via alias names in Verilog

I have a register:
reg [7:0] dout; //output of memory bus
Groups of bits in dout represent something meaningful like:
dout[2:0] is a state
dout[3] is a flag
dout[7:4] is some data
I want to read and write to this register dout from inside an always statement. I want to address it using these labels.
This example conveys my attempt:
reg [7:0] dout; //output of memory bus
wire [2:0] dout_state;
wire dout_flag;
wire [3:0] dout_data;
//alias labels
assign dout_state[2:0] = dout[2:0];
assign dout_flag = dout[3];
assign dout_data = dout[7:4];
always(#posedge clk) begin
dout_state <= 3'b1;
dout_flag <= 1'b1;
end
The procedural assignments fail because dout_state and dout_flag are wires.
I want these labels to work as aliases that represent portions of the dout bus.
How can I achieve this?
The always block already drives dout_state and dout_flag signals, so the other assignments should be reversed. Your current code never drives dout.
//alias labels
assign dout[2:0] = dout_state;
assign dout[3] = dout_flag;
assign dout[7:4] = dout_data;
Now the signal definitions also should be updated. If dout is a port, the reg definition should be removed. If not, it should be a wire.
wire [7:0] dout; //output of memory bus
Because of the always block, dout_state and dout_flag signals should be reg.
reg [2:0] dout_state;
reg dout_flag;

Error (10219): Verilog HDL Continuous Assignment error at Mux.v(19): object "muxout" on left-hand side of assignment must have a net type

I want to make Frequency Divider with Counter and MUX.
I make 3 module for project
// 4-bit Counter
module Counter (input clk, input reset, output reg[3:0] out);
always#(posedge clk or posedge reset)
begin
if(reset)
out = 4'b0000;
else
begin
if(clk)
if(out < 4'b1111)
out = out + 4'b0001;
else
out = 4'b0000;
end
end
endmodule
//module 4by1 Mux
module Mux (input [3:0] muxin , input [1:0] sel, output reg muxout);
function _4by1mux;
input [3:0] muxin;
input [1:0] sel;
case (sel)
2'b00 : _4by1mux = muxin[0];
2'b01 : _4by1mux = muxin[1];
2'b10 : _4by1mux = muxin[2];
2'b11 : _4by1mux = muxin[3];
endcase
endfunction
assign muxout = _4by1mux(muxin, sel);
endmodule
//module freqDivider
module freqDivider(input clk, input reset, input [1:0] sel, output reg muxout);
wire [3:0]counterbus;
Counter ct1 (clk, reset, counterbus);
Mux mux1 (counterbus, sel, muxout);
endmodule
module freqDivider is top, and I call module Counter and Mux
but module Mux has problem with
Error (10219): Verilog HDL Continuous Assignment error at Mux.v(19):
object "muxout" on left-hand side of assignment must have a net type
this error
ps. input sel will be changed by time
The error is a result of the muxout output having type reg instead of type wire. In verilog, lines can have two overarching types, either nets (like wire type) or variables (like reg types). To assign values/logic to net types, you need to use assign statements and not always blocks. To assign values/logic to variable types, you can only use always blocks and not assign statements. So, you can either make your assign in the Mux module an always block or, for an easier solution, don't make the muxout output a reg, just leave out the reg keyword and it will be a wire.
Error is that you have declared mux_out as reg type, instead of wire type. Default type of any port is wire. You are doing continuous assignment on that net through assign keyword. And on reg type nets, assignment can only be done inside procedural block (initial, always).
Change to mux_out from output reg to output only.

How to store input into reg from wire in verilog?

I' trying to store value from wire named 'in' into reg 'a'.
But, the problem is value of reg 'a' is showing 'xxxx' in simulator. However, value of wire 'in' is showing correctly.
My target is just to read value from input wire and store it into a register.
module test(
input [3:0] in,
output [3:0] out
);
reg [3:0] a;
initial
begin
a = in;
end
endmodule
The reason why the value of a is 'xxxx' in the simulation is probably that a is set to the value of in only a single time initially, and a may not yet have been set to any specific value at this time in the simulation.
Declaring a reg in Verilog does not necessarily mean that a hardware register is described by the code. That usually involves the use of a clock signal:
module test(
input clk,
input [3:0] in,
output [3:0] out
);
// this describes a register with input "in" and output "a"
reg [3:0] a;
always #(posedge clk) begin
a <= in;
end
// I assume you want "a" to be the output of the module
assign out = a;
endmodule
Here is a counter example where a reg is used to describe something which is not a register, but only a simple wire:
module not_a_register(
input in,
output out
);
reg a;
always #(in) begin
a <= in;
end
assign out = a;
endmodule
Also note that I have used the non-blocking assignment operator <= inside the always block, which is good practice when describing synchronous logic. You can read more about it here.

Use of wire inside an always block?

Can I use a wire inside an always block?
Like for example:
wire [3:0]a;
assign a=3;
always #(c)
begin
d=a+c;
end
It got compiled without throwing any error. Why?
Yes, you can use a wire's value inside an always block, you just can not assign a value to a wire in always or initial block.
The only real difference between a wire and reg is the syntax for assigning values.
In the above example d could also have been created as a wire, these are equivalent:
reg [3:0] answer_reg;
always #* begin
answer_reg = a + c;
end
wire [3:0] answer_wire;
assign answer_wire = a + c;

Resources