verilog assignment results in undefined 'X' output -- why? - verilog

I know VHDL, and just learning verilog. I'm trying to do a simple assignment with bit shift, and I get undefined 'X' in the result. I don't understand why. This is in simulation with Xilinx ISim software.
This assignment:
assign dout = $signed(data_out >>> shift_bits);
Results in 'X' wherever a '1' should be. For example, if data_out = '00001100', and shift_bits = 1, dout will = '00000XX0'.
Below is the module definition and the assignment operation:
module SensorINV(
input clk,
input [23:0] din,
input idv,
input [4:0] shift_bits,
output [23:0] dout,
output reg odv
);
reg [47:0] data_out = 0; // initialize the output
assign dout = $signed(data_out >>> shift_bits);
// assign dout = data_out[44:21]; // this didn't work either
reg [1:0] state = 0;
always #(posedge clk) begin
case (state)
0 : begin // waiting for new data
...
end
1 : begin
...
data_out <= data_out + temp1_w;
state <= 2;
end
2 : begin
...
state <= 0;
end
default : state <= 0;
endcase
end

The problem turned out to be conflicting drivers of dout, only one of which was shown in the code above. In the next module up, where this one was instantiated (not shown), I had a line like this:
wire [23:0] dout = 0;
This created a continuous assignment, not an initialization value. This conflict didn't show up in simulation until I tried to make dout non-zero. If it were a register reg, it would be an initialization value, but in this case it was a wire. Got rid of the continuous assign = 0, and problem solved.

Related

problem with flattening an array in verilog

I tried to flatten an array with numbers into a variable in order to pass it as an input to a module in verilog. But, I get the error:
Port 1 (DATA_IN) of process_data expects 64 bits, got 4096. Pruning
4032 high bits of the expression.
I know that my module process_data in not ready yet and hence it does not work properly, but my problem for now is that the input is a lot more bits than it should.
Do you know how could I fix it?
module process_data(input wire [63:0] DATA_IN , input wire [6:0]AdrR , input wire [6:0]AdrW, input R_W , input Cen, input clk, input reset, output reg [63:0]Reg_Data_Out);
integer i;
reg [63:0]Memory[63:0]; //64 * 64 bit array
initial
begin
i=0;
//++for
repeat (64)
begin
Memory[i]=64'd1; //64 = number of the thesis that the vector has
i=i+1;
end
end
always #(negedge(clk))
//initial AdrR ,AdrW = 0; // 7'b0000_000;
begin
if(Cen == 1'b1) begin // cen = chip enabled
case (R_W)
1'b1:
//++check if not empty
Reg_Data_Out = Memory[AdrR]; // (read) out put memory context
1'b0:
//++check if not full
Memory[AdrW] = DATA_IN; // write input to memory
default:
Reg_Data_Out = 64'bxxxxxxxx;
endcase
end
end
endmodule
module TOP();
reg [63:0] inputdata1 [0:127]; //array
reg [64*64-1:0] flattened_inputdata1;
reg [6:0] AddressR,AddressW;
reg cen,clk, R_W, reset;
wire [63:0] Data_Out;
//pass the numbers
integer count;
initial
begin
count = 0;
while (count < 128) // Execute loop till count is 127. exit at count 128
begin
// every timh that the integer variable count takes must be also passed into reg inputdata1
inputdata1[count] = count;
count = count + 1;
end
end
//flattening
initial
begin
count = 0;
while (count < 128) // Execute loop till count is 127. exit at count 128
begin
flattened_inputdata1[64*count +: 64] = inputdata1[count];
//flattened_inputdata1[(64*count) +63) : (64*count)] = inputdata1[count]; //declare a number is dekadikos
count = count + 1;
end
end
//call module for data I/O
process_data process_data( flattened_inputdata1, AddressR, AddressW, R_W , cen, clk, reset, Data_Out); //reset does not do anything yet
always #10 clk=~clk;
initial
begin
$display("flattenedinputdata1=%d", flattened_inputdata1);
cen=1'b1; //chip enabled
#50
R_W=1'b1; //read
AddressR=7'b0000_000;
#50
//R_W=1'b1; //read
//AddressR=7'b0000_001;
$finish; //#50 $finish;
end
endmodule
edaplayground link
You can see from the declarations that the sizes are different:
input wire [63:0] DATA_IN
and the thing you're passing in to it:
reg [64*64-1:0] flattened_inputdata1;
DATA_IN is 64 bits and flattened_inputdata1 is 4096 bits. So you'll need to change one of them so that the two sizes match.

Verilog reg assignment?

I'm totally new to Verilog programming and I do not understand where to initialize reg variables?
Let's have a look at the following snippets:
Edit:
Warning at synthesize
module test (
output LED0
);
reg led = 1'b1;
assign LED0 = led;
endmodule
or
module test (
output LED0
);
reg led;
initial begin
reg led <= 1'b1;
end
assign LED0 = led;
endmodule
Give me: Using initial value of led since it is never assigned at the line: reg led = 1'b1;
Are reg types only assigned in always# block?
Another example:
module fourBitCounter
(input clk,
output [3:0]counter
);
wire clk;
initial begin
reg[3:0] counter = 4'b1;
end
always# (posedge clk) begin
if(counter > 15)
counter <= 0;
else
counter <= counter + 1;
end endmodule
Here the reg has an initial value of 0 but I've set it before to 1... What's wrong? Thank you!
Are reg types only assigned in always# block?
No, reg types can be assigned in always blocks and initial blocks (plus task and function but I'll skip them in the scope of this question)
For your fourBitCounter, the reg[3:0] counter declared in the initial block creates a local variable also called counter that is only accessible within the scope of the block it was created in. You need to remove the reg[3:0] in the initial block so that the assignment get applied the the intended counter. But it will still not work because you declared counter as an inferred wire type and always/initial blocks cannot assign wires.
counter was declared as an output of a 4-bit inferred wire (output [3:0] counter is synonyms to output wire [3:0] counter). Since counter is assigned in an always block and initial block it needs to be a reg type. Therefore it should be declared as output reg [3:0] counter.
Also, you declared clk as in input and as a local wire, it cannot be both. Ports can be accessed locally, there is no reason to re-declare them as local nets.
FYI: for a 4-bit value, 15+1 equals 0 because there is nothing to store the MSB.
module fourBitCounter (
input clk,
output reg [3:0] counter // 'output reg', not 'output'
);
//wire clk; // do not do this, clk is an input
initial begin
counter = 4'b1; // no 'reg' here
end
always #(posedge clk) begin
if(counter > 15) // this will never evaluate as true with counter declared as 4-bit
counter <= 0;
else
counter <= counter + 1;
end
endmodule
For Verilog, assign statements can only be applied on net types (e.g. wire). This is legal:
module test ( output LED0 ); // LED0 is an inferred wire
assign LED0 = 1'b1;
endmodule
This is illegal:
module test ( output reg LED0 ); // Explicit reg
assign LED0 = 1'b1; // illegal, assign on a reg
endmodule
From your first code sample:
reg led; // <-- This declares one register called "led"
initial begin
reg led <= 1'b1; // <-- This declares a *separate* register called "led"
end // which is only valid in the initial block
The same issue exists in your second sample; you're declaring a separate register in the initial block. Don't use the keywords reg or wire if you're just trying to assign a value.

Verilog code does not print desired output

Can you tell me why this simple verilog program doesn't print 4 as I want?
primitive confrontatore(output z, input x, input y);
table
0 0 : 1;
0 1 : 0;
1 0 : 0;
1 1 : 1;
endtable
endprimitive
comparatore :
module comparatore (r, x, y);
output wire r;
input wire [21:0]x;
input wire [21:0]y;
wire [21:0]z;
genvar i;
generate
for(i=0; i<22; i=i+1)
begin
confrontatore t(z[i],x[i],y[i]);
end
endgenerate
assign r = & z;
endmodule
commutatore :
module commutatore (uscita_commutatore, alpha);
output wire [2:0]uscita_commutatore;
input wire alpha;
reg [2:0]temp;
initial
begin
case (alpha)
1'b0 : assign temp = 3;
1'b1 : assign temp = 4;
endcase
end
assign uscita_commutatore = temp;
endmodule
prova:
module prova();
reg [21:0]in1;
reg [21:0]in2;
wire [2:0]uscita;
wire uscita_comparatore;
comparatore c(uscita_comparatore, in1, in2);
commutatore C(uscita, uscita_comparatore);
initial
begin
in1 = 14;
$dumpfile("prova.vcd");
$dumpvars;
$monitor("\n in1 %d in2 %d -> uscita %d uscita_comparatore %d \n", in1, in2, uscita, uscita_comparatore);
#25 in2 = 14;
#100 $finish;
end
endmodule
The issue is in commutatore. You are using initial, which means the procedural block is only executed at time 0. At time 0, the input alpha is 1'bx, meaning temp is not assigned to anything. Instead of initial, use always #* which will execute the procedural block every time alpha changes.
Generally you should not assign statements in procedural blocks. It is legal Verilog however it is often the source of design bugs and synthesis support is limited.
always #*
begin
case (alpha)
1'b0 : temp = 3;
1'b1 : temp = 4;
default: temp = 3'bx; // <-- optional : to catch known to unknown transitions
endcase
end
The reason you are not getting 4 as you expect for an output is because your commutatore uses an initial block with assign statements in it when you wanted an always #* block to perform the combinational logic to get temp. initial blocks only fire once at the beginning of a simulation, while you want continuous assignment to act as combinational logic. Also, the assign statements in the block are not needed, they only make the simulation behave improperly for your purposes (typically, you will never need to use assign inside another block (initial,always,etc) as this has another meaning than simply set x to y.
For example, you really want something like this:
always #(*) begin
case (alpha)
1'b0: temp = 3'd3;
1'b1: temp = 3'd4;
endcase
end
Also, Verilog already has a build XNOR primative so your confrontatore is not needed, you can use xnor instead.

verilog- assign statement reg to output variable not being assigned

I am attempting to use an FPGA as a shift register to some LEDs with pwm, but ran into an error while trying to assign a reg containing the value shifted in to an output variable. When I upload it to the FPGA(i'm using the mojo by embedded micro), it does nothing. when I use the simulator, it reports that all of the output variables are never assigned and have the value of X, while all the other variables inside of the module work just fine. here is my code for the shifting module:
module shifting(
input clk,
input shiftingpin,//data to be shifted in
input rst,
output done,
output [3:0]data//pwm compare value output
);
reg [2: 0] ctr_d, ctr_q;
reg don;
reg [3:0]datas;
always #(*) begin
if(ctr_q == 3'b100) begin
ctr_d[2:0] = 3'b0;
don = 1'b1;
end else begin
ctr_d = ctr_q + 1'b1;
don = 1'b0;
end
end
always #(posedge clk) begin
datas[ctr_q] = shiftingpin;// assign value to the output
if (rst) begin
ctr_q <= 1'b0;
end else begin
ctr_q <= ctr_d;
end
end
assign data = datas;
assign done = don;
endmodule
done tells the containing module when to update and assign the value to pwm.
If I understood the question correctly you have a syntax error when trying to drive ports from within always blocks.
When declaring ports they are typically wire by default which can only be driven by ports or assign. Resulting in the code below
module shifting(
input clk,
input shiftingpin,
input rst,
output done,
output [3:0] data
);
reg don;
reg [3:0] datas;
assign done = don;
assign data = datas;
Solution
The solution is to define ports as reg, logic is preferred if you can support System Verilog.
logic will effectively switch between wire and reg as required to make refactoring code easier.
module shifting(
input clk,
input shiftingpin,
input rst,
output reg done,
output reg [3:0] data
);
always #(posedge clk) begin
data[ctr_q] <= shiftingpin; // <-- data port used directly
//...
NB: shift registers can be done with just
always #(posedge clk) begin
datas[3:0] <= {datas[2:0], shiftingpin};

how to map reg values to the ports of other module

i am an amateur in verilog. i am trying to call module divider. but i get errors like "Reference to vector reg 'qtnt' is not a legal net lvalue" in synthesis. i have tried using wires as inputs but when i tried to assign values to them an error message was recieved. please help
module euclid_mul(
input[9:0] p0,p1,q0,
input[19:0] tot,
input clk,
output reg [20:0] p2,
output reg out_en,o1,o2
);
reg[20:0] dvr,dvd,qtnt,rem;
reg[9:0] ph;
reg[20:0] mul,res;
reg enable,f1;
initial f1=0;
initial enable=0;
divider div2(dvd,dvr,enable,qtnt,rem,f1);
always # (negedge clk)
begin
if(f1==0) begin
mul=q0*p1;
ph=p0;
res={11'b00000000000,ph[9:0]}-mul;
if(res[20])
begin
o1=1;
dvd=-res;
end
else
dvd=res;
o2=1;
dvr=tot;
enable=1;
end
end
always #(posedge f1)
begin
if(res[20])
begin
p2=tot-rem;
out_en=1;
end
else
begin
p2=rem;
out_en=1;
end
end
endmodule
You may get more response if you formatted the code so that it was easier to read. Something like the following:
I have also pointed out a section where I think you are missing a begin and end statement.
Also inside clocked sections you often want to use nonblocking assignments <=.
Since you have not provided the divider module, I would prefer to see ports named rather than specified in order, it might help us to know what it is likely to do, even better label it with its direction and width.
module euclid_mul(
input [9:0] p0,p1,q0,
input [19:0] tot,
input clk,
output reg [20:0] p2,
output reg out_en,o1,o2
);
reg [20:0] dvr,dvd,qtnt,rem;
reg [9:0] ph;
reg [20:0] mul,res;
reg enable,f1;
initial begin
f1 = 0;
enable = 0;
end
divider div2(dvd,dvr,enable,qtnt,rem,f1);
// My prefered style to help us understand conectivity.
//divider
// divider_i0(
// .divisor( dvd ), //input [20:0]
// .result ( res ) //output [20:0]
//);
always # (negedge clk) begin
if(f1==0) begin
mul = q0*p1;
ph = p0;
res = {11'b00000000000,ph[9:0]}-mul;
if ( res[20] ) begin
o1 = 1;
dvd = -res;
end
else begin //There was a missing begin
dvd = res;
o2 = 1;
dvr = tot;
enable = 1;
end //Missing End
end
end
always #(posedge f1) begin
if(res[20]) begin
p2 = tot-rem;
out_en = 1;
end
else begin
p2 = rem;
out_en = 1;
end
end
endmodule
Inputs can be regs and driven from inside always or initial blocks, or wires driven from a single assign or another modules output.
Outputs should always be connected to wires, the module drives them.

Resources