Verilog error: # KERNEL: hold=xxxxxxxx - verilog

I am using Aldec Active HDL Simulator and I am Trying to access an array in my verilog code. When I simulate it, it gives:
XXXXXXX (unknown in hold and outb2 variable ).
Both hold and outb are array.
Here is my code (Design Block)----
module design_blk(input wire clk,input wire sw1,input wire sw2,input wire sw3,input wire start,output reg[7:0 ]out,output reg rs,output reg rw,output reg en);
//Slow Clock Instance
wire sclk;
sender send1(clk,sclk);
//Releated to Braun Multiplier
reg [3:0]a=4'b0000;
reg [3:0]b=4'b0000;
wire [7:0]outb;
reg[7:0]outb2[255:0]; //use for holdin outb value
reg[7:0]hold[255:0];//Used for Holding Output/Return of Function
braun sd(.x(a),.y(b),.out(outb));
integer state5=0; //State for start checking
//Integer for Array for a & b
integer s=0;
reg cnt=1'b0;
always #(posedge sclk)
begin
//Fault Checking Condition
if( (start==1'b0) & (sw3==1'b0) & (cnt==1'b0))
begin
case(state5)
0:begin
a<=4'b1000;
s<=s+1;
b<=b + 1'b1;
hold[s]<=ora(a,b);
$display("hold=%b and s=%d",hold[s],s);
outb2[s]<=outb;
$display("outb2=%band s=%d",outb2[s],s);
if(s!=15)
begin
state5<=0;
end
else if(s==15)
begin
state5<=1;
end
end
1:begin
a<=4'b0001;
s<=s+1;
b<=b+ 1'b1;
hold[s]<=ora(a,b);
$display("hold=%b and s=%d",hold[s],s);
outb2[s]<=outb;
$display("outb=%b and s=%d",outb2[s],s);
if(s!=31)
begin
state5<=1;
end
else if(s==31)
begin
cnt<=1'b1;
$display("I am in last s=%d",s);
end
end
endcase
end //if end
end//always end
//Function For ORA Checking Purpose......
function [7:0]ora (input reg [3:0]X,input reg [3:0]Y);
begin
$display("X=%b & Y=%b",X,Y);
//Positive-Positive Operations
ora=X * Y;
end
endfunction
endmodule
and here is my another file of Counter(i named it sender.v) file-
`timescale 1ns / 1ps
module sender(input wire clkin, output reg clkout);
reg [2:0]tmp=3'b000;
//Delay Generation////////
always#(posedge clkin)
begin
tmp <= tmp+1'b1;
clkout<=tmp[2];
end
endmodule
and the file of Multiplier(Braun Multiplier) is here-
module braun(x,y,out);
input wire [3:0]x;
input wire [3:0]y; //Input/Output Port Declarations
output [7:0]out;
wire [5:0]a;
wire [8:0]b;
wire [5:0]sa;
wire [1:0]cc;
//If we place 1'b0 in place of "zero"then this was not work so we use this...
wire k[8:0];
//There are 16 And Gates used here....
and a1(out[0],x[0],y[0]);
and a2(a[0],x[1],y[0]);
and a3(a[1],x[2],y[0]);
and a4(a[2],x[3],y[0]);
and a5(b[0],x[0],y[1]);
and a6(b[1],x[1],y[1]);
and a7(b[2],x[2],y[1]);
and a8(a[3],x[3],y[1]);
and a9(b[3],x[0],y[2]);
and a10(b[4],x[1],y[2]);
and a11(b[5],x[2],y[2]);
and a12(a[4],x[3],y[2]);
and a13(b[6],x[0],y[3]);
and a14(b[7],x[1],y[3]);
and a15(b[8],x[2],y[3]);
and a16(a[5],x[3],y[3]);
//There are 12 Full Adder used here....
full_adder f1(out[1],k[0],a[0],b[0],1'b0);
full_adder f2(sa[0],k[1],a[1],b[1],1'b0);
full_adder f3(sa[1],k[2],a[2],b[2],1'b0);
full_adder f4(out[2],k[3],sa[0],b[3],k[0]);
full_adder f5(sa[2],k[4],sa[1],b[4],k[1]);
full_adder f6(sa[3],k[5],a[3],b[5],k[2]);
full_adder f7(out[3],k[6],sa[2],b[6],k[3]);
full_adder f8(sa[4],k[7],sa[3],b[7],k[4]);
full_adder f9(sa[5],k[8],a[4],b[8],k[5]);
full_adder f10(out[4],cc[0],sa[4],k[6],1'b0);
full_adder f11(out[5],cc[1],sa[5],k[7],cc[0]);
full_adder f12(out[6],out[7],a[5],k[8],cc[1]);
endmodule
module full_adder(output reg sum,output reg carry,input wire a,input wire b,input wire c);
always#(a,b,c)
begin
case({a,b,c})
3'b000:begin
sum=1'b0;
carry=1'b0;
end
3'b001:begin
sum=1'b1;
carry=1'b0;
end
3'b010:begin
sum=1'b1;
carry=1'b0;
end
3'b011:begin
sum=1'b0;
carry=1'b1;
end
3'b100:begin
sum=1'b1;
carry=1'b0;
end
3'b110:begin
sum=1'b0;
carry=1'b1;
end
3'b111:begin
sum=1'b1;
carry=1'b1;
end
3'b101:begin
sum=1'b0;
carry=1'b1;
end
endcase
end
endmodule
and the Testbench code is here-
module top;
reg start;
reg sw3;
reg clk=1'b0;
lcdfgh lcd(clk,,,sw3,start,,,,);
initial
begin
sw3=1'b0;
start=1'b0;
end
always
begin
#20 clk=!clk;
end
endmodule
Simulator Gives this Error-
# KERNEL: hold=xxxxxxxx
# KERNEL: outb2=xxxxxxxx
What does the error mean?

I didn't go through all you code, it is a little bit hard to be understand. But what I want to say is you simulator should have the capability to trace 'X'. Trace the driver back from the first 'X' you found. Good Look.

s goes out of range for the index of hold and outb2. Add s your display message and you'll see s is greater than 255 (the max index of hold and outb2) when Xs are read out. Out of range assignments will never assign anything. When reading from out of range, the value will always be the default value of the type. The default value of a reg is X.
Other issue: Non-blocking assignment (<=) should be use when assigning sequential logic.

Related

Calculating square root

I write code to calculate perfect square of number, but I am not getting proper output. I take input b and regs a, d. Firstly, I put 1 in d, then square it and store in a. Then compare with input - if it is not satisfied then increment d. But at output I am getting is square = XXXX.
My code:
module square_root(b,clk,square);
input [3:0] b;
input clk;
output [3:0]square;
reg[3:0]a,square;
reg[2:0] d;
initial
begin
d<=3'b001;
end
always#(clk)
begin
a<=d*d;
if(a==b)
square<=a;
else
d<=d+1;
end
endmodule
change this
initial
begin
d<=3'b001;
end
TO
initial
begin
d=3'b001;
end
Test Bench:
module TB_SQT;
reg [3:0]b;
reg clk;
wire [3:0]square;
square_root SQT(b,clk,square);
initial
begin
clk=0;
b=9;
end
always
#1 clk=!clk;
endmodule
module Sqrt(
input clk,
input [3:0]in,
output reg [3:0]out);
reg [3:0]temp=1;
always#(posedge clk)
begin
if((temp*temp)==in)
out<=temp;
else
temp<=temp+1;
end
endmodule
Test Bench:
module TB_Sqrt;
reg clk;
reg [3:0]in;
wire [3:0]out;
Sqrt SQRT(clk,in,out);
initial
begin
clk=0;
in=9;
end
always
#2 clk=!clk;
endmodule
Not probably the best code...but hey

Unable to find bug in Simulator, because $display & Wave window of simulator Show Different Result?

I am try to design a BIST (Built in Self Test System) For Multiplier. I created a Multiplier which is working fine and now I try to compare its result(Multiplier's output) with the correct result of(ORA's output). I am simulating with the Modelsim's Simulator. I don't understand why the waveform is showing different results than from the $display task. ....... I am blank now and not know what to do .........help me
Here is my code (Top level module)----
module top(input wire clk,input wire sw1,input wire sw2,input wire sw3,input wire start,output reg[7:0 ]out,output reg rs,output reg rw,output reg en);
//Slow Clock Instance
wire sclk;
sender send1(clk,sclk);
//Releated to Braun Multiplier
reg [3:0]a=4'b0000;
reg [3:0]b=4'b0000;
wire [7:0]outb;
reg[7:0]hold;//Used for Holding Output/Return of Function
braun sd(.x(a),.y(b),.out(outb));
integer state5=0; //State for start checking
//Integer for Array for a & b
integer s=0;
reg cnt=1'b0;
always #(posedge sclk)
begin
//Fault Checking Condition
if( (start==1'b0) & (sw3==1'b0) & (cnt==1'b0) )
begin:close
case(state5)
0:begin
a=4'b0100;
s=s+1;
b=b + 1'b1;
hold=ora(a,b);
$display("hold=%b",hold);
$display("outb=%b",outb);
if(s!=15)
begin
if(outb==hold)
begin
state5=0;
end
else if(outb!=hold)
begin
cnt=1'b1;
disable close;
end
end
else if(s==15)
begin
if(outb==hold)
begin
s=0;
state5=1;
end
else if(outb!=hold)
begin
cnt=1'b1;
disable close;
end
end
end
1:begin
a=4'b0001;
s=s+1;
b=b+ 1'b1;
hold=ora(a,b);
$display("hold=%b",hold);
$display("outb=%b",outb);
if(s!=15)
begin
if(outb==hold)
begin
state5=1;
end
else if(outb!=hold)
begin
cnt=1'b1;
disable close;
end
end
else if(s==15 )
begin
if(outb==hold)
begin
s=0;
state5=2;
end
else if(outb!=hold)
begin
cnt=1'b1;
disable close;
end
end
end
2:begin
a=4'b0010;
s=s+1;
b=b+ 1'b1;
hold=ora(a,b);
$display("hold=%b",hold);
$display("outb=%b",outb);
if(s!=15)
begin
if(outb==hold)
begin
state5=2;
end
else if(outb!=hold)
begin
cnt=1'b1;
disable close;
end
end
else if(s==15 )
begin
if(outb==hold)
begin
s=0;
state5=3;
end
else if(outb!=hold)
begin
cnt=1'b1;
disable close;
end
end
end
endcase
end //if end
end//always end
//Function For ORA Checking Purpose......
function [7:0]ora (input reg [3:0]X,input reg [3:0]Y);
begin
$display("X=%b & Y=%b",X,Y);
//Positive-Positive Operations
ora=X * Y;
end
endfunction
endmodule
and here is my another file of Counter(i named it sender.v) file-
`timescale 1ns / 1ps
module sender(input wire clkin, output reg clkout);
reg [2:0]tmp=3'b000;
//Delay Generation////////
always#(posedge clkin)
begin
tmp <= tmp+1'b1;
clkout<=tmp[2];
end
endmodule
and the file of Multiplier(Braun Multiplier) is here-
module braun(x,y,out);
input wire [3:0]x;
input wire [3:0]y; //Input/Output Port Declarations
output [7:0]out;
wire [5:0]a;
wire [8:0]b;
wire [5:0]sa;
wire [1:0]cc;
//If we place 1'b0 in place of "zero"then this was not work so we use this...
wire k[8:0];
//There are 16 And Gates used here....
and a1(out[0],x[0],y[0]);
and a2(a[0],x[1],y[0]);
and a3(a[1],x[2],y[0]);
and a4(a[2],x[3],y[0]);
and a5(b[0],x[0],y[1]);
and a6(b[1],x[1],y[1]);
and a7(b[2],x[2],y[1]);
and a8(a[3],x[3],y[1]);
and a9(b[3],x[0],y[2]);
and a10(b[4],x[1],y[2]);
and a11(b[5],x[2],y[2]);
and a12(a[4],x[3],y[2]);
and a13(b[6],x[0],y[3]);
and a14(b[7],x[1],y[3]);
and a15(b[8],x[2],y[3]);
and a16(a[5],x[3],y[3]);
//There are 12 Full Adder used here....
full_adder f1(out[1],k[0],a[0],b[0],1'b0);
full_adder f2(sa[0],k[1],a[1],b[1],1'b0);
full_adder f3(sa[1],k[2],a[2],b[2],1'b0);
full_adder f4(out[2],k[3],sa[0],b[3],k[0]);
full_adder f5(sa[2],k[4],sa[1],b[4],k[1]);
full_adder f6(sa[3],k[5],a[3],b[5],k[2]);
full_adder f7(out[3],k[6],sa[2],b[6],k[3]);
full_adder f8(sa[4],k[7],sa[3],b[7],k[4]);
full_adder f9(sa[5],k[8],a[4],b[8],k[5]);
full_adder f10(out[4],cc[0],sa[4],k[6],1'b0);
full_adder f11(out[5],cc[1],sa[5],k[7],cc[0]);
full_adder f12(out[6],out[7],a[5],k[8],cc[1]);
endmodule
module full_adder(output reg sum,output reg carry,input wire a,input wire b,input wire c);
always#(a,b,c)
begin
case({a,b,c})
3'b000:begin
sum=1'b0;
carry=1'b0;
end
3'b001:begin
sum=1'b1;
carry=1'b0;
end
3'b010:begin
sum=1'b1;
carry=1'b0;
end
3'b011:begin
sum=1'b0;
carry=1'b1;
end
3'b100:begin
sum=1'b1;
carry=1'b0;
end
3'b110:begin
sum=1'b0;
carry=1'b1;
end
3'b111:begin
sum=1'b1;
carry=1'b1;
end
3'b101:begin
sum=1'b0;
carry=1'b1;
end
endcase
end
endmodule
Because I don't have 10 reputation I am unable to post image please check this in your Modelsim...
and the ouput of Transcript window is here which show different result is here-
# X=0100 & Y=0001
# hold=00000100
# outb=00000000
The waveform is showing the values at end of each timestep. Your call to $display will execute in the active events region of the scheduler timestep where the following can occur in any order:
Execute all module blocking assignments.
Evaluate the Right-Hand-Side (RHS) of all nonblocking assignments and schedule updates
into the NBA region.
Execute all module continuous assignments
Evaluate inputs and update outputs of Verilog primitives.
Execute the $display and $finish commands.
You are probably seeing different results due to the unknown order that these events are scheduled. The waveform will show what happened after all these events have run. More information from testbench.in:
According to scheduling semantics of verilog, $display executes before the nonblocking statements update LHS. Therefore if $display contains LHS variable of nonblocking assignment, the results are not proper. The $strobe command shows updated values at the end of the time step after all other commands, including nonblocking assignments, have completed.
I'd suggest it's worth writing a separate self-checking testbench rather than relying on $display calls to check your functionality. Note also that you can share code examples (with waveforms) on EDA Playground.

LC-3 16 bit processor wrong simulation in Verilog

I am working on designing a LC-3(Little Computer) CPU. I have designed PC unit, Control Unit(as Finite State Machine), Instruction Memory, ALU unit and Data Memory in Modules. There is also a Register File unit which works as Main, module calls are done in this unit.
I want the program to work as when PCread is 1, get the variable that going to be assigned to out from in variable, and when PCwrite is 1, just increment the out variable. out is the address that sent to the Instruction Memory.
The problem is when I simulate, instruction never loads to the Instruction Memory. Because PCwrite does not work for the first state of the Control Unit, because I reset both PCread and PCread variables in the first state. I do this because I do not want the instruction to load until one instruction finishes it work. I could not find a way to handle this.
I know if this is solved, processor will work because when I try it for one instruction with initialized values, it works.
module reg_fileandMain();
parameter B=16, W=3;
reg Clk;
wire wr_en;
wire [W-1:0] w_addr, r_addr1, r_addr2;
wire [B-1:0] inData;
wire [B-1:0] r_data1;
wire [B-1:0] r_data2;
wire [B-1:0] address;
wire Dataout;
wire InsMemRead;
reg [15:0] extended, mux1out, mux2out, mux3out, mux4out, mux5out;
wire ALUout, incrementer;
wire [15:0] instruction;
reg [B-1:0] array_reg[2**W-1:0];
wire mux1,mux3,mux4,mux5;
wire [1:0] mux2;
initial begin
mux5out=16'hFFFF;
end
wire MemRead,PCwrite,ALUcontrol,MemWrite,PCread;
always#(posedge Clk)
begin
if(wr_en)begin
array_reg[w_addr]<=inData;
end
end
assign r_data1=array_reg[r_addr1];
assign r_data2=array_reg[r_addr2];
controlUnit controlUnit0(Clk,instruction,mux1,mux2,mux3,mux4,mux5,InsMemRead,MemRead,PCwrite,wr_en,ALUcontrol,MemWrite,PCread,r_addr1,r_addr2,w_addr);
PCunit PCunit0(Clk,PCwrite,PCread,mux5out,address);
DataMem DataMem0(Clk,mux2out,r_data1,MemRead,MemWrite,Dataout);
ALU ALU0(mux1out,r_data2,ALUout,ALUcontrol);
InstructionMemory InstructionMemory0(Clk,address,InsMemRead,instruction);
always #* begin
if(mux1)begin
extended = { {11{instruction[4]}}, instruction[4:0] };
mux1out=extended;
end
else begin
mux1out=r_data1;
end
if(mux2==2'b00)begin
mux2out=ALUout;
end
else if(mux2==2'b01)begin
extended = instruction[8:0];
mux2out=extended;
end
else if(mux2==2'b11)begin
extended = instruction[8:0];
mux2out=extended;
end
if(mux3)begin
mux3out<=mux2out;
end
else begin
mux3out<=Dataout;
end
if(mux4)begin
mux4out<=address;
end
else begin
mux4out<=mux3out;
end
if(mux5)begin
mux5out<=address;
end
else begin
mux5out<=mux3out;
end
end
assign inData=mux4out;
always begin
#20 Clk<=0;
#20 Clk<=1;
end
endmodule
module controlUnit(Clk,in,mux1,mux2,mux3,mux4,mux5,InsMemRead,MemRead,PCwrite,WE,ALUcontrol,MemWrite,PCread,rd1,rd2,wr);
input Clk;
input [15:0] in;
output reg mux1,mux3,mux4,mux5,InsMemRead,MemRead,PCwrite,WE,ALUcontrol,MemWrite,PCread;
output reg [1:0] mux2;
reg [3:0] state,stateNext;
reg counter;
output wire [2:0] rd1,rd2,wr;
initial begin
state=4'b0000;
stateNext=4'b0001;
MemRead=0;
PCwrite=1;
end
assign rd1=in[2:0];
assign rd2=in[8:6];
assign wr=in[11:9];
always #* begin
if (state==4'b0000)begin
stateNext=4'b0001;
PCwrite=0;
PCread=0;
end
if(state==4'b0001)
begin
InsMemRead<=1;
if(in[15:12]==4'b0100)begin
stateNext=4'b0100;
InsMemRead=1'b1;
end
else if( in[15:12]==4'b1000)begin
stateNext=4'b0100;
InsMemRead=1;
end
else if(in[15:12]==4'b0010)begin
stateNext=4'b0010;
InsMemRead=1;
end
else if(in[15:12]==4'b1100)begin
stateNext=4'b1100;
InsMemRead=1;
end
else if(in[15:12]==1010)begin
stateNext=4'b1010;
InsMemRead=1;
end
end
else if(state==4'b0100)begin
stateNext=4'b0101;
end
else if(state==4'b0101)begin
stateNext=4'b0000;
mux3=0;
mux4=0;
WE=1;
mux2=2'b01;
MemRead=1;
mux5=1;
PCwrite=1;
end
else if(state==4'b1000)begin
stateNext=4'b0000;
mux1=in[5];
ALUcontrol=0;
mux3=1;
mux4=0;
WE=1;
PCwrite=1;
end
else if(state==4'b0010)begin
stateNext=4'b0000;
mux1=in[5];
ALUcontrol=1;
mux3=1;
mux4=0;
WE=1;
PCwrite=1;
end
else if(state==4'b1100)begin
stateNext=4'b0000;
mux2=2'b01;
MemWrite=1;
PCwrite=1;
end
else if(state==4'b1010)begin
stateNext=4'b0000;
mux2=2'b11;
mux3=1;
mux5=0;
PCread=1;
end
end
always #(posedge Clk) begin
state = stateNext;
end
endmodule
module PCunit(Clk,PCwrite,PCread,in,out);
input Clk,PCread,PCwrite;
input wire [15:0] in;
output reg [15:0] out;
always #(posedge Clk) begin
if(PCwrite)
begin
out<=out+1;
end
else
begin
if(PCread)
begin
out<=in;
end
end
end
endmodule
module ALU(in1,in2,ALUout,ALUcontrol);
input ALUcontrol;
input wire [15:0] in1, in2;
output reg [15:0] ALUout;
always #* begin
if(ALUcontrol)
ALUout = in1 + in2;
else
ALUout = in1 & in2;
end
endmodule
module DataMem(Clk,AddrReg,in,MemRead,MemWrite,out);
input Clk, MemRead, MemWrite;
input [15:0] AddrReg, in;
output reg [15:0] out;
reg[15:0] Mem[2**9:0];
always #(posedge Clk) begin
if(MemWrite)begin
Mem[AddrReg]=in;
end
end
always #* begin
if(MemRead) begin
out=Mem[AddrReg];
end
end
endmodule
module InstructionMemory(Clk,address,InsMemRead,instruction);
input Clk;
input [15:0] address;
input InsMemRead;
output reg [15:0] instruction;
reg [15:0] InstructionMemory [15:0];
initial begin
$readmemh("AssemblerOutput.hex", InstructionMemory);
end
always#(posedge Clk)begin
if(InsMemRead)
instruction=InstructionMemory[address];
end
endmodule
Always use #* for sensitivity lists for combinational logic. Change:
always #(MemRead) begin
to:
always #* begin
Your always block is not sensitive to changes in AddrReg.
I found that one way to solve this is sending a signal from the PC unit to control unit that the instruction adress is sent to instruction memory with an output reg variable, and check if this variable is changed in control unit, if it is, reset the PCwrite variable. Thanks to all tried to help.

Simulating LC3-16 bit processor in Verilog

I am a newbie in Verilog. I am working on designing a LC-3(Little Computer) CPU. I have designed PC unit, Control Unit(as Finite State Machine), Instruction Memory, ALU unit and Data Memory in Modules. There is also a Register File unit which works as Main, module calls are done in this unit.
The problem is when I try to simulate the program, only change that I saw is Clock rises and the Instruction assign to the Instruction wire from the Instruction Memory. I expect the Controller Unit assign the values to the variables like MemRead, PCread, PCwrite etc. at the clock rises, because as Clk rises, stateNext is assigned to the state.
What could be my mistake? Any helps and suggestions are highly appriciated. Here is what I done with the Register File Unit with Controller Unit module:
module reg_fileandMain();
parameter B=16, W=3;
reg Clk;
wire wr_en;
wire [W-1:0] w_addr, r_addr1, r_addr2;
wire [B-1:0] inData;
wire [B-1:0] r_data1;
wire [B-1:0] r_data2;
wire [B-1:0] address;
wire Dataout;
reg [15:0] extended, mux1out, mux2out, mux3out, mux4out, mux5out;
wire ALUout, incrementer;
wire [15:0] instruction;
reg [B-1:0] array_reg[2**W-1:0];
wire mux1,mux3,mux4,mux5;
wire [1:0] mux2;
wire MemRead,PCwrite,ALUcontrol,MemWrite,PCread;
always#(posedge Clk)
begin
if(wr_en)begin
array_reg[w_addr]<=inData;
end
end
assign r_data1=array_reg[r_addr1];
assign r_data2=array_reg[r_addr2];
controlUnit controlUnit0(Clk,instruction,mux1,mux2,mux3,mux4,mux5,MemRead,PCwrite,wr_en,ALUcontrol,MemWrite,PCread,r_addr1,r_addr2,w_addr);
PCunit PCunit0(Clk,PCwrite,PCread,mux5out,address);
DataMem DataMem0(Clk,mux2out,r_data1,MemRead,MemWrite,Dataout);
ALU ALU0(mux1out,r_data2,ALUout,ALUcontrol);
InstructionMemory InstructionMemory0(address,instruction);
always #(mux1,mux2,mux3,mux4,mux5) begin
if(mux1)begin
extended = { {11{instruction[4]}}, instruction[4:0] };
mux1out=extended;
end
else begin
mux1out=r_data1;
end
if(mux2==2'b00)begin
mux2out=ALUout;
end
else if(mux2==2'b01)begin
extended = instruction[8:0];
mux2out=extended;
end
else if(mux2==2'b11)begin
extended = instruction[8:0];
mux2out=extended;
end
if(mux3)begin
mux3out=mux2out;
end
else begin
mux3out=Dataout;
end
if(mux4)begin
mux4out=address;
end
else begin
mux4out=mux3out;
end
if(mux5)begin
mux5out=address;
end
else begin
mux5out=mux3out;
end
end
assign inData=mux4out;
always begin
#20 Clk<=0;
#20 Clk<=1;
end
endmodule
module controlUnit(Clk,in,mux1,mux2,mux3,mux4,mux5,MemRead,PCwrite,WE,ALUcontrol,MemWrite,PCread,rd1,rd2,wr);
input Clk;
input [15:0] in;
output reg mux1,mux3,mux4,mux5,MemRead,PCwrite,WE,ALUcontrol,MemWrite,PCread;
output reg [1:0] mux2;
reg [3:0] state,stateNext;
output wire [2:0] rd1,rd2,wr;
initial begin
state=4'b0111;
stateNext=4'b0000;
MemRead=0;
end
assign rd1=in[2:0];
assign rd2=in[8:6];
assign wr=in[11:9];
always #* begin
if (state==4'b0000)begin
stateNext=4'b0001;
PCread=1;
end
else if(state==4'b0001 && in[15:12]==0100)begin
stateNext=4'b0100;
MemRead=1;
end
else if(state==4'b0001 && in[15:12]==1000)begin
stateNext=4'b0100;
MemRead=1;
end
else if(state==4'b0001 && in[15:12]==0010)begin
stateNext=4'b0010;
MemRead=1;
end
else if(state==4'b0001 && in[15:12]==1100)begin
stateNext=4'b1100;
MemRead=1;
end
else if(state==4'b0001 && in[15:12]==1010)begin
stateNext=4'b1010;
MemRead=1;
end
else if(state==4'b0100)begin
stateNext=4'b0101;
end
else if(state==4'b0101)begin
stateNext=4'b0000;
mux3=0;
mux4=0;
WE=1;
mux2<=2'b01;
MemRead=1;
PCwrite=1;
end
else if(state==4'b1000)begin
stateNext=4'b0000;
mux1=in[5];
ALUcontrol=0;
mux3=1;
mux4=0;
WE=1;
PCwrite=1;
end
else if(state==4'b0010)begin
stateNext=4'b0000;
mux1=in[5];
ALUcontrol=1;
mux3=1;
mux4=0;
WE=1;
PCwrite=1;
end
else if(state==4'b1100)begin
stateNext=4'b0000;
mux2<=2'b01;
MemWrite=1;
PCwrite=1;
end
else if(state==4'b1010)begin
stateNext=4'b0000;
mux2<=2'b11;
mux3=1;
mux5=0;
PCwrite=1;
end
end
always #(posedge Clk) begin
state = stateNext;
end
endmodule
module ALU(in1,in2,ALUout,ALUcontrol);
input ALUcontrol;
input wire [15:0] in1, in2;
output reg [15:0] ALUout;
always #(in1, in2) begin
if(ALUcontrol)
ALUout = in1 + in2;
else
ALUout = in1 & in2;
end
endmodule
module InstructionMemory(address,instruction);
input [15:0] address;
output [15:0] instruction;
reg [15:0] InstructionMemory [15:0];
initial begin
$readmemh("AssemblerOutput.hex", InstructionMemory);
end
assign instruction=InstructionMemory[address];
endmodule
module DataMem(Clk,AddrReg,in,MemRead,MemWrite,out);
input Clk, MemRead, MemWrite;
input [15:0] AddrReg, in;
output reg [15:0] out;
reg[15:0] Mem[2**9:0];
always #(posedge Clk) begin
if(MemWrite)begin
Mem[AddrReg]=in;
end
end
always #(MemRead) begin
if(MemRead) begin
out=Mem[AddrReg];
end
end
endmodule
module PCunit(Clk,PCwrite,PCread,in,out);
input Clk,PCwrite,PCread;
input wire [15:0] in;
output reg [15:0] out;
initial begin
out=16'h0000;
end
always #(posedge Clk) begin
if(PCwrite==1)begin
out=out+1;
end
if(PCread==1)begin
out=in;
end
end
endmodule
In controlUnit, change:
always # (posedge state) begin
to:
always #* begin
Your next-state logic should be combinational. The posedge might treat the next-state logic as sequential. It is very strange to use posedge with a 4-bit signal.

Simulation output is all zeroes

My code for the design block and the testbench compiles; however, when I simulate, I'm not getting the correct output. Can anyone tell me where I'm going wrong in my code?
Here is the code for testbench:
module testbench;
reg [511:0]FROM_LS;
reg CLK;
reg [63:0]TO_IF_ID;
initial
begin
CLK= 0;
TO_IF_ID[63:0]=63'b0;
FROM_LS[511:480]= 32'b00011_00000_00100_01100_11100_10111_01;
FROM_LS[479:448]=32'b00_11000_00100_01111_11111_00011_10000;
end
always
begin
#10 CLK= ~ CLK;
//FROM_LS[511:448]= ~ FROM_LS[511:448];
$display("FROM_LS= %b", FROM_LS);
$display("TO_IF_ID= %b", TO_IF_ID);
end
endmodule
and here is the code for the design block:
module inst_line_buffer(input wire [511:0]from_LS,
input wire clk,
output reg [63:0]to_if_id);
parameter mem_size=16;
integer k;
reg [31:0] ilb[0:mem_size-1];
initial
begin
for (k = 0; k < mem_size ; k = k + 1)
begin
ilb[k] = 32'b00;
//$display ("ilb= %b",ilb[k]);
end
end
always #(posedge clk)
begin
ilb[0]= from_LS[511:480];
ilb[1]= from_LS[479:448];
ilb[2]= from_LS[447:416];
ilb[3]= from_LS[415:384];
ilb[4]= from_LS[383:352];
ilb[5]= from_LS[351:320];
ilb[6]= from_LS[319:288];
ilb[7]= from_LS[287:256];
ilb[8]= from_LS[255:224];
ilb[9]= from_LS[223:192];
ilb[10]= from_LS[191:160];
ilb[11]= from_LS[159:128];
ilb[12]= from_LS[127:96];
ilb[13]= from_LS[95:64];
ilb[14]= from_LS[63:32];
ilb[15]= from_LS[31:00];
to_if_id [63:32]= ilb[0];
to_if_id [31:0]= ilb[1];
$display("ilb= %b", ilb[1]);
end
endmodule
I'm expecting that the value of TO_IF_ID should be 0001100000001000110011100101110100110000010001111111110001110000, but I'm getting all zeros.
When you run a simulation on your testbench module, TO_IF_ID is always 0 because you only assigned a value to it once at time 0 in your initial block. If you want the value to change, it needs to be driven somehow.
As Andy pointed out in a comment, you probably meant to instantiate the inst_line_buffer module in your testbench. Verilog will not do this magically for you. But then, you should declare TO_IF_ID as a wire instead of a reg and remove it from the initial block.
module testbench;
reg [511:0]FROM_LS;
reg CLK;
wire [63:0]TO_IF_ID;
inst_line_buffer inst_line_buffer (
.from_LS (FROM_LS),
.clk (CLK),
.to_if_id (TO_IF_ID)
);
initial begin
CLK= 0;
FROM_LS[511:480]= 32'b00011_00000_00100_01100_11100_10111_01;
FROM_LS[479:448]=32'b00_11000_00100_01111_11111_00011_10000;
#500 $finish;
end
always
begin
#10 CLK= ~ CLK;
//FROM_LS[511:448]= ~ FROM_LS[511:448];
$display("FROM_LS= %b", FROM_LS);
$display("TO_IF_ID= %b", TO_IF_ID);
end
endmodule

Resources