我们的任务是在Verilog中构建一个基本的单循环CPU,但我没有得到更正确的基本模块。例如,为了测试指令存储器模块,我们已经给出了一个文本文件“hw3Test.txt”,其中包含十六进制指令,我正试图将其粘贴到IM中。
00221820
AC010000
8C240000
10210001
00001820
00411822
当我运行测试平台时,我发现进入内存的唯一指令是第二,第三和第四行。这是IM模块:
module IM(addr, clk, inst);
input [31:0] addr;
input clk;
output reg [31:0] inst;
reg [31:0] mem [255:0];
initial begin
$readmemh("hw3Test.txt", mem);
end
always @( posedge clk) begin
inst=mem[addr[31:2]];
end
endmodule
测试平台:
module imtest;
// Inputs
reg [31:0] addr;
reg clk;
// Outputs
wire [31:0] inst;
// Instantiate the Unit Under Test (UUT)
IM uut (
.addr(addr),
.clk(clk),
.inst(inst)
);
initial begin
// Initialize Inputs
addr = 0;
clk = 0;
// Wait 100 ns for global reset to finish
#100;
// Add stimulus here
clk = 0;
addr = 0;
#100;
forever begin
#20;
clk = ~clk;
addr = addr + 4;
end
end
endmodule
我也不确定我是否正确使用PC-to-IM模块,因为除了初始值之外,除了rst和clk信号之外的所有信号都没有显示有效值。谁能指出我哪里出错?
module pc_im(
// Inputs
rst, clk, PCin,
// Outputs
inst, PCout
);
input clk, rst;
input [31:0] PCin;
output reg [31:0] inst;
output reg [31:0] PCout;
PC mypc (
.clk(clk),
.rst(rst),
.PCin(PCin),
.PCout(PCout)
);
IM myim(
.clk(clk),
.addr(PCout),
.inst(inst)
);
endmodule
这是PC.v模块:
module PC(rst, clk, PCin, PCout);
input clk, rst;
input [31:0] PCin;
output reg [31:0] PCout;
always @(posedge clk) begin
if (rst) PCout <= 0;
else PCout <= PCin + 4;
end
endmodule
最后,测试平台:
module pcimtest;
// Inputs
reg rst;
reg clk;
reg [31:0] PCin;
// Outputs
wire [31:0] inst;
wire [31:0] PCout;
// Instantiate the Unit Under Test (UUT)
pc_im uut (
.rst(rst),
.clk(clk),
.PCin(PCin),
// Outputs
.inst(inst),
.PCout(PCout)
);
initial begin
// Initialize Inputs
rst = 1;
clk = 0;
PCin = 0;
// Wait 100 ns for global reset to finish
#100;
rst = 0;
forever begin
#100;
clk <= ~clk;
PCin <= PCout;
end
// Add stimulus here
end
endmodule
答案 0 :(得分:2)
以下是一些看起来令人怀疑的事情。
在用于推断寄存器的块中使用非阻塞分配通常是好的。
即。变化
always @( posedge clk) begin
inst=mem[addr[31:2]];
end
到
always @( posedge clk) begin
inst<=mem[addr[31:2]];
end
您每个时钟周期更改两次信号,一次在负边沿,一次在正边沿。
变化:
forever begin
#20;
clk = ~clk;
addr = addr + 4;
end
到
forever begin
#20;
clk = 1;
#20;
clk = 0;
addr = addr + 4;
end
您正在使用同步复位但在复位期间不提供时钟。
考虑代码
always @(posedge clk) begin
if (rst) PCout <= 0;
else PCout <= PCin + 4;
end
此块仅在正时钟边沿激活。但是,在时钟暂停时将复位设为高电平,因此不会发生复位。
更改
rst = 1;
clk = 0;
PCin = 0;
// Wait 100 ns for global reset to finish
#100;
到
rst = 1;
clk = 0;
PCin = 0;
#20
clk = 1;
#20
clk = 0;
// Wait 100 ns for global reset to finish
#100;