Issues with my Verilog Simulation -x's and z's in signals - verilog
I have a project, in which I have to implement a list processor that computes the squared-norm of a complex vector.
EDITED:
My code is compiling, and the simulation is working, and I corrected all the connections, so my input signals are reading values. But I am having some trouble with the "start" signal. In the testbench I set it to 0. then to 1 but for some reason it remains 0. Anyone know why a signal would usually stay 0 even though it was assigned to a particula value in the test bench??
I'm still amateurish in verilog, so I'm not sure what I did wrong. I've been tracking every module used, checked if there were errors in instantiating, but I'm missing something, silly or fundamental. I just have no idea what it is.
Here is the code: the total modules are control, memory, datapath, testbench and VNLP (aka the module that computes the squared-norm).
module control (output reg [7:0] counter, output reg add1_sel, add2_sel, before_sel, next_sel, acc_sel, A1_sel, A2_sel, load_before, load_next, load_acc, done_op, input clk, start_op);
wire [9:0] one, zero, before, next;
//reg [7:0] counter;
reg [1 : 0] state, next_state;
parameter Start=0, Compute=1, GetNext=2, Done=3;
reg counter_start, counter_incr;
assign one=before;
assign zero=next;
always#(posedge clk) begin
if (start_op) state<=Start;
else state<=next_state;
end
always#(posedge clk) begin
if (counter_start ==1)
counter<=0;
else if(counter_incr==1)
counter<=counter+1;
end
always#(state, start_op, zero, one) begin
load_acc=0;
next_sel=0;
before_sel=0;
A1_sel=0;
A2_sel=0;
load_next=0;
load_before=0;
done_op=0;
acc_sel=0;
add1_sel=0;
add2_sel=0;
counter_incr=0;
counter_start=0;
case(state)
Start:
begin
next_sel=0;
before_sel=0;
load_next=1;
load_before=1;
acc_sel=0;
load_acc=1;
counter_start=1;
add1_sel=0;
add2_sel=0;
//load_M1=0;
//load_M2=0;
done_op=0;
if (start_op ==0) next_state=Compute;
//else next_state=Start;
end
Compute:
begin
counter_start=0;
next_sel=1;
before_sel=1;
load_next=0;
load_before=0;
A1_sel=1;
A2_sel=1;
add1_sel=1;
add2_sel=1;
//load_M1=1;
//load_M2=1;
load_acc=1;
acc_sel=1;
done_op=0;
if (start_op ==0) next_state=GetNext;
//else next_state=Start;
end
GetNext:
begin
load_next=1;
load_before=1;
A1_sel=0;
A2_sel=0;
load_acc=0;
done_op=0;
if (start_op ==0) begin
if (zero==0 || one==1) next_state= Done;
else if (!start_op && zero!=0 && one!=1) begin next_state=Compute; counter_incr=1; end
end
end
Done:
begin
done_op=1;
load_acc=0; counter_incr=0;
if (start_op ==1) next_state=Start;
//else next_state=Done;
end
default: next_state= Start;
endcase
end
endmodule
module memory (D1, D2, A1, A2);
parameter word_size=10;
parameter address_size=9;
parameter memory_size= 512;
reg [9:0] memory [memory_size-1:0];
output reg [word_size-1:0] D1;
output reg [word_size-1:0] D2;
input [address_size-1:0] A1;
input [address_size-1:0] A2;
always#(*) begin
D1=memory[A1];
D2=memory[A2];
end
endmodule
module VNLP (
output reg[27: 0] norm2, output reg[7:0] len, output reg Done, input reg done_op, output reg [8:0] A1, A2, input [7:0] counter,
input [9:0] D1, D2, output reg [9:0] Next, Before, output reg [27:0] Accumulator,
input add1_sel, add2_sel, before_sel, next_sel, acc_sel, A1_sel, A2_sel, load_before, load_next, load_acc,clk, start_op);
reg [19:0] adder1, adder2;
wire [20:0] sum_add;
reg [27:0] acc;
reg [9:0] before, next;
reg [8:0] a1, a2;
reg [19:0] d1, d2;
//assign d1= D1*D1;
//assign d2=D2*D2;
assign sum_add= adder1 + adder2;
always#(*) begin
if (add2_sel) begin adder2=D2*D2; end
else adder2=20'b0;
if (add1_sel) adder1=D1*D1;
else adder1=20'b0;
if (before_sel) before=D2;
else before=10'b0;
if (next_sel) next=D1;
else next=10'b0;
if (acc_sel) acc=sum_add+ Accumulator;
else acc=28'b0;
if (A1_sel) A1<=Next+ 2'b10;
else A1<=Next;
if (A2_sel) A2<=Before+ 2'b10;
else A2<=Before;
if (done_op) begin
norm2<= Accumulator;
len=counter;
Done=1;
end
else begin
norm2<=28'b0;
len<=8'b0;
Done<=0;
end
end
always#(posedge clk) begin
if (load_before) Before<= before;
end
always#(posedge clk) begin
if (load_next) Next<= next;
end
always#(posedge clk) begin
if (load_acc) Accumulator<= acc;
end
endmodule
module Datapath (
input start_op, clk,
output Done,
output [7:0] len,
output [27:0] norm2);
wire [8:0] A1, A2;
wire [9:0] D1, D2;
wire done_op;
wire [7:0] counter;
wire [9:0] Next, Before;
wire [27:0] Accumulator;
wire add1_sel, add2_sel, before_sel, next_sel, acc_sel, A1_sel, A2_sel, load_before, load_next, load_acc;
VNLP VNLP(norm2, len, Done, done_op, A1, A2, counter, D1, D2, Next, Before,Accumulator,
add1_sel, add2_sel, before_sel, next_sel, acc_sel, A1_sel, A2_sel,
load_before, load_next, load_acc,clk, start_op);
memory M1 (D1, D2, A1, A2);
control control (counter,add1_sel, add2_sel, before_sel, next_sel, acc_sel, A1_sel, A2_sel, load_before, load_next, load_acc, done_op, clk, start_op);
endmodule
module Datapath_tb;
reg start_op, clk;
wire Done;
wire [7:0] len;
wire [27:0] norm2;
reg[8:0] k;
wire[9:0] word0,word1,word2,word3,
word4,word5,word6,word7,
word8,word9,word10,word11,
word12,word13,word14,word15,
word16,word17,word18,word19,
word20, word21,word22,word23,
word24,word25,word26,word27,
word28,word29,word30,word31,
word32, word33,word34,word35,
word36,word37,word38,word39;
Datapath Datapath (
start_op, clk,
Done,
len,
norm2);
assign word0 = Datapath.M1.memory[0];
assign word1 = Datapath.M1.memory[1];
assign word2 = Datapath.M1.memory[2];
assign word3 = Datapath.M1.memory[3];
assign word4 = Datapath.M1.memory[5];
assign word5 = Datapath.M1.memory[6];
assign word6 = Datapath.M1.memory[7];
assign word7 = Datapath.M1.memory[8];
assign word8 = Datapath.M1.memory[11];
assign word9 = Datapath.M1.memory[12];
assign word10 = Datapath.M1.memory[13];
assign word11 = Datapath.M1.memory[14];
assign word12 = Datapath.M1.memory[17];
assign word13 = Datapath.M1.memory[18];
assign word14 = Datapath.M1.memory[19];
assign word15 = Datapath.M1.memory[20];
assign word16 = Datapath.M1.memory[22];
assign word17 = Datapath.M1.memory[23];
assign word18 = Datapath.M1.memory[24];
assign word19 = Datapath.M1.memory[25];
assign word20 = Datapath.M1.memory[28];
assign word21 = Datapath.M1.memory[29];
assign word22 = Datapath.M1.memory[30];
assign word23 = Datapath.M1.memory[31];
assign word24 = Datapath.M1.memory[33];
assign word25 = Datapath.M1.memory[34];
assign word26 = Datapath.M1.memory[35];
assign word27 = Datapath.M1.memory[36];
assign word28 = Datapath.M1.memory[39];
assign word29 = Datapath.M1.memory[40];
assign word30 = Datapath.M1.memory[41];
assign word31 = Datapath.M1.memory[42];
assign word32 = Datapath.M1.memory[44];
assign word33 = Datapath.M1.memory[45];
assign word34 = Datapath.M1.memory[46];
assign word35 = Datapath.M1.memory[47];
assign word36 = Datapath.M1.memory[49];
assign word37 = Datapath.M1.memory[50];
assign word38 = Datapath.M1.memory[51];
assign word39 = Datapath.M1.memory[52];
//VNLP VNLP(norm2, len, done, A1, A2, counter, D1, D2, Next, Before,Accumulator, add1_sel, add2_sel, before_sel, next_sel, acc_sel, A1_sel, A2_sel, load_before, load_next, load_acc,clk, start);
//Flush memory
initial
begin: Flush
start_op=0; clk=0;
for (k=0; k<=52; k=k+1) Datapath.M1.memory[k] = 0;
end
initial
begin: Load
#5
#5 start_op=1; #5 start_op=0;
Datapath.M1.memory[0] = 49;
Datapath.M1.memory[1] = 34;
Datapath.M1.memory[2] = -33;
Datapath.M1.memory[3] = 23;
Datapath.M1.memory[5] = 17 ;
Datapath.M1.memory[6]=40;
Datapath.M1.memory[7] = 19;
Datapath.M1.memory[8]=102;
Datapath.M1.memory[11] = 22;
Datapath.M1.memory[12]=18;
Datapath.M1.memory[13] = 25;
Datapath.M1.memory[14] = -93;
Datapath.M1.memory[17]=11;
Datapath.M1.memory[18] = 6;
Datapath.M1.memory[19] = 8 ;
Datapath.M1.memory[20]=90;
Datapath.M1.memory[22] = 33;
Datapath.M1.memory[23] = 12;
Datapath.M1.memory[24] = 31;
Datapath.M1.memory[25] = 32;
Datapath.M1.memory[28] = 102;
Datapath.M1.memory[29] = 240;
Datapath.M1.memory[30]=47;
Datapath.M1.memory[31] = -11;
Datapath.M1.memory[33] = 0;
Datapath.M1.memory[34]=23;
Datapath.M1.memory[35] = 25;
Datapath.M1.memory[36] = 88;
Datapath.M1.memory[39]=5;
Datapath.M1.memory[40] = 50;
Datapath.M1.memory[41] = 56;
Datapath.M1.memory[42] = 48;
Datapath.M1.memory[44] = 56;
Datapath.M1.memory[45] = 88;
Datapath.M1.memory[46] = 112;
Datapath.M1.memory[47] = 69;
Datapath.M1.memory[49] = 39;
Datapath.M1.memory[50] = 1;
Datapath.M1.memory[51] = 101;
Datapath.M1.memory[52] = 63;
end
always forever #5 clk=~clk;
endmodule
And this is an idea of the architecture if that helps:
Architecture Schematic for processor
Usually you get Z's on inputs because you have not connected up things correctly. Check your inputs for missing connections or typos before trying to diagnose the outputs.
It seems that you are not connecting the control module in the top level (datapath module of your code). There are initiations of VNLP and memory modules but not the control module. You have assigned the same names to inputs of the VNLP and the outputs of control module, however this does not ensure that they are connected. Thus, control module is not used in your design and this is probably the reason why the inputs and outputs are not working.
Related
Machine state does not change output
As you can see in the code below, I have a machine state with a state called start. This state should take the value of coord_x_reg , increment it by one and assign it to the output port using the assign instruction at the end. The problems are: The output coord_x does not change in the simulation as you can see in the photo I imagine that the problem is that I cannot write and read from the register at the same time. How can I achieve the effect I want then? (I also tried using coord_x_reg as a integer variable) When using reset, I have to comment some signals, other way I get Illegal left hand side of nonblocking assignment error. module Ball #(parameter SCR_W = 1280, //SCREEN RESOLUTION? parameter SCR_H = 720, parameter BALL_WIDTH = 30, parameter PAD_Y_WIDTH = 26, parameter PAD_Y_LENGTH = 168, parameter PAD_x_POS_L = 67, parameter PAD_x_POS_R = 1213 //SCR_W-PAD_x_POS_L ) ( input wire CLK, RST, input wire button_L, button_R, input wire [9:0] pad_y_L, input wire [9:0] pad_y_R, output wire [9:0] coord_x, output wire [9:0] coord_y, output wire [3:0] score_left, output wire [3:0] score_right ); //STATES localparam [3:0] //11 states needed we need 4 bits start = 4'b0000, start_race = 4'b0001, left_player_begins = 4'b0010, right_player_begins = 4'b0011, top_left = 4'b0100, top_right = 4'b0101, bottom_left = 4'b0110, bottom_right = 4'b0111, score_L = 4'b1000, score_R = 4'b1001, game_over = 4'b1010; //Current state variables reg [3:0] state_reg, state_next; //output registers reg [9:0] coord_x_reg = 0; reg [9:0] coord_y_reg = 0; reg [3:0] score_left_reg = 0; reg [3:0] score_right_reg = 0; always #(posedge CLK, posedge RST) begin if(RST) // go to state zero if reset begin state_reg <= start; //coord_x <= 0; //coord_y <= 0; //score_left <= 0; //score_right <= 0; end else // otherwise update the states begin state_reg <= state_next; end end //_________________________________________________________________________ // MACHINE STATE DESIGN //_________________________________________________________________________ always #(state_reg) // <------------ PUT VARIABLES HERE???????!!!!!!!!!!!!!!! begin // store current state as next state_next = state_reg; // REQUIRED: when no case statement is satisfied case(state_reg) start : begin coord_x_reg <= coord_x_reg + 1; if (coord_x_reg == 10) state_next = start_race; end start_race : begin state_next = start; end endcase end assign coord_x = coord_x_reg; assign coord_y = coord_y_reg; assign score_left = score_left_reg; assign score_right = score_right_reg; endmodule // Ball
By investigating, I came to the conclusion that the sensibility list was giving problems. I modified the code so the machine state is inside the always #(posedge CLK, posedge RST). Now works as expected. The new code: module Ball #(parameter SCR_W = 1280, //SCREEN RESOLUTION? parameter SCR_H = 720, parameter BALL_WIDTH = 30, parameter PAD_Y_WIDTH = 26, parameter PAD_Y_LENGTH = 168, parameter PAD_x_POS_L = 67, parameter PAD_x_POS_R = 1213 //SCR_W-PAD_x_POS_L ) ( input wire CLK, RST, input wire button_L, button_R, input wire [9:0] pad_y_L, input wire [9:0] pad_y_R, output wire [9:0] coord_x, output wire [9:0] coord_y, output wire [3:0] score_left, output wire [3:0] score_right ); //STATES localparam [3:0] //11 states needed we need 4 bits start = 4'b0000, start_race = 4'b0001, left_player_begins = 4'b0010, right_player_begins = 4'b0011, top_left = 4'b0100, top_right = 4'b0101, bottom_left = 4'b0110, bottom_right = 4'b0111, score_L = 4'b1000, score_R = 4'b1001, game_over = 4'b1010; //Current state variables reg [3:0] state; //output registers reg [9:0] coord_x_reg = 0; reg [9:0] coord_y_reg = 0; reg [3:0] score_left_reg = 0; reg [3:0] score_right_reg = 0; always #(posedge CLK, posedge RST) begin if(RST) // go to state zero if reset begin state <= start; coord_x <= 0; coord_y <= 0; score_left <= 0; score_right <= 0; end else // otherwise update the states begin case(state) start : begin coord_x_reg = coord_x_reg + 1; if (coord_x_reg == 10) state = start_race; end start_race : begin state = start_race; end endcase end end assign coord_x = coord_x_reg; assign coord_y = coord_y_reg; assign score_left = score_left_reg; assign score_right = score_right_reg; endmodule // Ball ```
Unexpected high impedance output
I'm writing an ALU for a processor I'm designing (first RTL project) and I'm getting a high impedance output on ALU_out when I run my testbench, even though the flags do get set and are output correctly. module alu( input clk, input reset, input [7:0] A, B, input [3:0] Op_Sel, output [7:0] ALU_out, output C, V, N, Z ); reg [8:0] Result = 0; reg [8:0] cn_temp = 0; reg [7:0] v_temp = 0; reg carry = 0; reg overflow = 0; reg negative = 0; reg zero = 0; assign ALU_Out = Result[7:0]; assign C = carry; assign V = overflow; assign N = negative; assign Z = zero; always #* begin if (reset) begin Result = 0; cn_temp = 0; v_temp = 0; carry = 0; overflow = 0; negative = 0; zero = 0; end end always #(posedge clk) begin case(Op_Sel) 4'b0000: // Addition begin Result = A + B; negative = Result[7]; zero = (Result[7:0] == 8'b00000000); carry = Result[8]; v_temp = A[6:0] + B[6:0]; overflow = v_temp[7] ^ carry; end . . //The rest of the instructions . . . endcase end endmodule //My testbench module alu_testbench(); reg clk; reg reset; reg [7:0] A; reg [7:0] B; reg [3:0] Op_Sel; wire [7:0] ALU_out; wire C, V, N, Z; always begin #1 clk = ~clk; end initial begin clk = 0; reset = 0; #1 reset = 1; #1 reset = 0; end initial begin #10 A=2; B=3; Op_Sel = 4'b0000; #10 A=1; end alu alu ( .clk(clk), .A(A), .B(B), .Op_Sel(Op_Sel), .ALU_out(ALU_out), .C(C), .V(V), .N(N), .Z(Z)); endmodule I believe I connected up the module to the testbench (through a wire), so why am I getting high impedance on ALU_out?
This was a tricky typo. You mistakenly used an upper-case "O" in the ALU_Out signal name. Since Verilog is case-sensitive, this is a different signal from ALU_out. It is not mandatory to declare all signals in Verilog. However, you can use the following compiler directive in your code to help catch this type of common problem: `default_nettype none Your simulator should generate an error. To fix it, change: assign ALU_Out = Result[7:0]; to: assign ALU_out = Result[7:0]; My simulators also generated a warning message because you didn't drive the reset input of alu. Here is the fix: alu alu ( .clk(clk), .reset(reset), /// <------ add this .A(A), .B(B), .Op_Sel(Op_Sel), .ALU_out(ALU_out), .C(C), .V(V), .N(N), .Z(Z));
How do I resolve Verilog simulation error: "Too many port connections. Expected 8, found 9" in ModelSim
I'm trying to build an 8-bit multiplier in Verilog, but I keep running in to this weird error when I go to simulate my module's test bench. It says: Too many port connections. Expected 8, found 9 This doesn't really make any sense seeing as how both the module AND the test bench have 9 variables listed. Any help will be much appreciated! Multiplier Module module my8bitmultiplier (output [15:0] O, output Done, Cout, input [7:0] A, B, input Load, Clk, Reset, Cin); reg Done; reg [1:0] state; reg [7:0] A_reg, B_reg; reg [15:0] A_temp, B_temp, O_temp, O_reg; my16bitadder Adding(O_temp, Cout,A_temp,B_temp, Cin); always#(posedge Clk) begin if(Reset) assign state = {2'b00}; case(state) 0: if(Load) begin A_reg = A; B_reg = B; O_reg = A_reg; state = 1; end 1: begin A_temp = A_reg; B_temp = O_reg; B_reg = B_reg - 1; state = 2; end 2: begin O_reg = O_temp; if(B_temp) begin state = 1; end else begin state = 3; Done = 1'b1; end end 3: begin Done = 1'b0; state = 0; end endcase end endmodule Testbench module my8bitmultiplier_tb; reg Load, Clk, Reset, Cin; reg [7:0] A, B; wire [15:0] O; wire Done, Cout; my8bitmultiplier dut(O, Done, Cout, A, B, Load, Clk, Reset, Cin); always #5 Clk = ~Clk; initial begin A = 8'b10; B = 8'b10; Load = 1; Cin = 0; #10 Load = 0; #3000 A = 8'd100; #3000 B = 8'd100; #3000 Load = 1; #3010 Load = 0; #6000 A = 8'd150; #6000 B = 8'd150; #6000 Load = 1; #6000 Load = 0; begin $display ($time,"A= %d B= %d O=%d ", A, B, O); end #10000 $finish; end endmodule
When I run you code on another simulator, I get a more helpful warning message: reg Done; | xmvlog: *W,ILLPDX : Multiple declarations for a port not allowed in module with ANSI list of port declarations (port 'Done') [12.3.4(IEEE-2001)]. The warning goes away when I delete this line: reg Done; and change: module my8bitmultiplier (output [15:0] O, output Done, Cout, input [7:0] A, B, input Load, Clk, Reset, Cin); to: module my8bitmultiplier (output [15:0] O, output reg Done, Cout, input [7:0] A, B, input Load, Clk, Reset, Cin); Perhaps that solves your problem on modelsim. You can also try your code on different simulators on edaplayground. You will sometimes get more helpful messages.
Always loop that does not assign the outputs
I am making an average that resets every period on EDA Playground. No errors are displayed on the simulator, Icarus Verilog, but the outputs are continually unassigned (which, of course, is not what I intended). Here is my design: module shift ( input [13:0] in, input clock, output [31:0] sum, output [14:0] avg); integer reset; reg [31:0] sum_reg; reg [14:0] avg_reg; always #(posedge clock) if (reset == 8) begin avg_reg = sum_reg >> 3; sum_reg = 0; reset = 0; end else begin sum_reg = sum_reg + in; reset = reset + 1; end assign sum = sum_reg; assign avg = avg_reg; endmodule Here is my testbench: module shift_tb; reg [13:0] in; reg clock = 1'b0; reg reset; wire [31:0] sum; wire [14:0] avg; shift s ( .in(in), .clock(clock), .sum(sum), .avg(avg)); integer f; initial begin for (f = 9000; f < 10000; f = f + 10) begin in = f; $display("in = %d, sum = %d, avg = %d", in, sum, avg); end end always #1 clock = ~clock; endmodule What is wrong with this code?
One problem is reset is an integer that is initially x and stays that way. You need a way of initializing it to 0. Another problem is your testbench for-loop has no delay. You should add #(nedgedge clk)
Missing output on register file simulation
I'm trying to simulate a register file. My issues is that I am not getting an output for aData or bData. I suspect I have an issue with my assignments but I'm not sure. Still somewhat new to Verilog. My code for the module: `timescale 1ns / 1ps module registerfile( input [4:0] aAddress, input [4:0] bAddress, input [4:0] dAddress, input [31:0] dData, input write, input [3:0] status, input clock, input reset, output reg [31:0] aData, output reg [31:0] bData ); reg [31:0] registerfile [0:31]; integer i; initial begin for (i = 0; i <32; i = i +1 ) begin registerfile[i] = 0; end end always # (*) begin if (aAddress == 5'b00000) begin aData = 32'h0000_0000; //reg[0] already holds 0 end else begin aData = registerfile[aAddress]; //contents of register file at aAddress sent out to aData end end always # (*) begin if (bAddress == 5'b00000) begin bData = 32'h0000_0000; //reg[0] already holds 0 end else begin bData = registerfile[bAddress]; //contents of register file at bAddress sent out to bData end end always # (posedge clock) begin if (reset == 1) begin for (i = 0; i < 32; i = i + 1) begin registerfile[i] <= 0; aData = 0; bData = 0; end end else if ((write == 1) && (dAddress != 0) && (dAddress != 31)) //reserve reg 0 for 0 constant and 31 for status register begin registerfile[dAddress] <= dData; //store dData if (aAddress == dAddress) //handles special case aData <= dData; if (bAddress == dAddress) //handles special case bData <= dData; end registerfile[31] <= {28'd0, status}; //status flags end endmodule My code for the simulation: `timescale 1ns / 1ps module registerfile_test; // Inputs reg [4:0] aAddress; reg [4:0] bAddress; reg [4:0] dAddress; reg [31:0] dData; reg write; reg [3:0] status; reg clock; reg reset; // Outputs wire [31:0] aData; wire [31:0] bData; // Instantiate the Unit Under Test (UUT) registerfile uut ( .aAddress(aAddress), .bAddress(bAddress), .dAddress(dAddress), .dData(dData), .write(write), .status(status), .clock(clock), .reset(reset), .aData(aData), .bData(bData) ); reg [31:0] registerfile [0:31]; reg [31:0] testData1, testData2; initial begin // Initialize Inputs aAddress = 0; bAddress = 0; dAddress = 0; dData = 0; write = 0; clock = 0; reset = 0; // Wait 100 ns for global reset to finish #100; testData1 = 32'hFF0F_00FF; testData2 = 32'h00F0_FF00; aAddress = 5'b00101; bAddress = 5'b00010; dAddress = 5'b00110; dData = 32'hFFFF_FFF0; //used to test write = 1; status = 4'b0000; //write = 0; registerfile[aAddress] = testData1; registerfile[bAddress] = testData2; end // Add stimulus here always begin #10 clock = ~clock; end endmodule
You are assigning to aData in two separate always blocks. You shouldn't do that. Likewise for bData. Also, reset is always 0 in your testbench.