单周期CPU设计(二)取指模块(minisys)(verilog)(vivado)
`timescale 1ns / 1ps
//
module Ifetc32 (
inputreset,// 复位信号(高电平有效)
inputclock,// 时钟(23MHz)
output[31:0]Instruction,// 输出指令到其他模块
output[31:0]PC_plus_4_out,// (pc+4)送执行单元
input[31:0]Add_result,// 来自执行单元,算出的跳转地址
input[31:0]Read_data_1,// 来自译码单元,jr指令用的地址
inputBranch,// 来自控制单元
inputnBranch,// 来自控制单元
inputJmp,// 来自控制单元
inputJal,// 来自控制单元
inputJrn,// 来自控制单元
inputZero,// 来自执行单元
output[31:0]opcplus4,// JAL指令专用的PC+4
// ROM Pinouts
output[13:0]rom_adr_o,// 给程序ROM单元的取指地址
input[31:0]Jpadr// 从程序ROM单元中获取的指令
);
wire [31:0] PC_plus_4;
reg [31:0] PC;
reg [31:0] next_PC;// 下条指令的PC(不一定是PC+4)
reg [31:0] opcplus4;
// ROM Pinouts
assign rom_adr_o = PC[15:2];
assign Instruction = Jpadr;
assign PC_plus_4[31:2] = PC[31:2] + 4;
assign PC_plus_4[1:0] = 2'b00;
assign PC_plus_4_out = PC_plus_4[31:0];
always @* begin // beq $n ,$m if $n=$m branch bne if $n /=$m branch jr
if (Branch && Zero) begin
next_PC = PC + Add_result;
end else if (nBranch && !Zero) begin
next_PC = PC + Add_result;
end else if (Jrn) begin
next_PC = Read_data_1;
end else begin
next_PC = PC_plus_4;
end
end
// 请考虑以上三条指令的判断条件,
// 以及三条指令的执行该给next_PC赋什么值
always @(negedge clock) begin
if (reset) begin
PC <= 32'h00000000;
opcplus4 <= 32'h00000000;
end else begin
PC <= next_PC;
if (Jal) begin
opcplus4 <= PC + 4;
end else begin
opcplus4 <= 32'h00000000;
end
end
end
endmodule
仿真代码如下
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date:
// Design Name:
// Module Name: ifetc32_sim
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module ifetc32_sim ();
// input
reg[31:0] Add_result = 32'h00000000;
reg[31:0] Read_data_1 = 32'h00000000;
reg Branch = 1'b0;
reg nBranch = 1'b0;
reg Jmp = 1'b0;
reg Jal = 1'b0;
reg Jrn = 1'b0;
reg Zero = 1'b0;
reg clock = 1'b0,reset = 1'b1;
// output
wire [31:0] Instruction; // 输出指令
wire [31:0] PC_plus_4_out;
wire [31:0] opcplus4;
wire [13:0] rom_adr;
wire [31:0] Jpadr;
Ifetc32 Uif (
.reset(reset),// 复位(高电平有效)
.clock(clock),// CPU时钟
.Instruction(Instruction),// 输出指令到其他模块
.PC_plus_4_out(PC_plus_4_out),// (pc+4)送执行单元
.Add_result(Add_result),// 来自执行单元,算出的跳转地址
.Read_data_1(Read_data_1),// 来自译码单元,jr指令用的地址
.Branch(Branch),// 来自控制单元
.nBranch(nBranch),// 来自控制单元
.Jmp(Jmp),// 来自控制单元
.Jal(Jal),// 来自控制单元
.Jrn(Jrn),// 来自控制单元
.Zero(Zero),// 来自执行单元
.opcplus4(opcplus4),// JAL指令专用的PC+4
// ROM Pinouts
.rom_adr_o(rom_adr),// 给程序ROM单元的取指地址
.Jpadr(Jpadr)// 从程序ROM单元中获取的指令
);
// 分配64KB ROM, 编译器实际只用 64KB ROM
prgrom instmem (
.clka(clock),
.wea(0),
.addra(rom_adr),
.dina(0),
.douta(Jpadr)
);
initial begin
#100 reset = 1'b0;
#100 Jal = 1;
#100 begin Jrn = 1;Jal = 0; Read_data_1 = 32'h0000019c;end;
#100 begin Jrn = 0;Branch = 1'b1; Zero = 1'b1; Add_result = 32'h00000020;end;
#100 begin Branch = 1'b0; Zero = 1'b0; end;
end
always #50 clock = ~clock;
endmodule
仿真波形图如下
原文地址:https://blog.csdn.net/m0_74626628/article/details/140555221
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!