Experiment content
1. Learn the design of instruction memory
2. Master the method and process of CPU instruction fetching and instruction decoding
Solution
1. This experiment design uses the Harvard structure to design the memory module, and it is necessary to design a read-only memory as the instruction memory, which is realized by the Memory IP core (you will not use the Memory IP core, you can see my blog post Memory Experiment
2. Program Counter PC and PC Self-incrementing instruments are combined into a module. Because the instruction memory has only 64 32-bit units, the upper 24 bits of the PC's 32-bit instruction address can be directly cleared in the design.
3. Note that the fetch is executed on the rising edge of the instruction cycle clk Command operation, update the PC value on the falling edge of clk
4. Code display:
top module
module Fetch_Inst_Code(clk,rst,LED,MUX,op_code,funct,rs_addr,rt_addr,rd_addr,shamt,Inst_code);
input clk,rst;
input [1:0]MUX;
output [31:0]Inst_code;
output reg[7:0]LED;
reg [31:0]PC;
wire [31:0]PC_new;
output [5:0]op_code,funct;
output [4:0]rs_addr,rt_addr,rd_addr,shamt;
PC pc1(clk,rst,Inst_code);
always@(*)
begin
case(MUX)
2'b00:LED = Inst_code[7:0];
2'b01:LED = Inst_code[15:8];
2'b10:LED = Inst_code[23:16];
2'b11:LED = Inst_code[31:25];
endcase
end
assign op_code = Inst_code[31:26];
assign rs_addr = Inst_code[25:21];
assign rt_addr = Inst_code[20:16];
assign rd_addr = Inst_code[15:11];
assign shamt = Inst_code[10:6];
assign funct = Inst_code[5:0];
endmodule
PC (instruction fetch module)
module PC(clk,rst,Inst_code);
input clk,rst;
wire [31:0]PC_new;
reg[31:0]PC;
initial
PC = 32'h0000_0000;
output [31:0]Inst_code;
assign PC_new = PC +4;
Inst_Rom your_instance_name (
.clka(clk), // input clka
.addra(PC[7:2]), // input [5 : 0] addra
.douta(Inst_code) // output [31 : 0] douta
);
always@(negedge clk or posedge rst)
begin
if(rst)
begin PC <= 32'B0000_0000; end
else
begin PC <=PC_new; end
end
endmodule
Friendly reminder: PC must be initialized, otherwise the result will be deviated.
Test module
module test;
// Inputs
reg clk;
reg rst;
reg [1:0] MUX;
// Outputs
wire [7:0] LED;
wire [5:0] op_code;
wire [5:0] funct;
wire [4:0] rs_addr;
wire [4:0] rt_addr;
wire [4:0] rd_addr;
wire [4:0] shamt;
wire [31:0] Inst_code;
Fetch_Inst_Code uut (
.clk(clk),
.rst(rst),
.LED(LED),
.MUX(MUX),
.op_code(op_code),
.funct(funct),
.rs_addr(rs_addr),
.rt_addr(rt_addr),
.rd_addr(rd_addr),
.shamt(shamt),
.Inst_code(Inst_code)
);
always #33 clk = ~clk;
initial begin
clk = 0;
rst = 1;
MUX = 0;
#2;
rst = 0;
end
endmodule
MIPS32.coe
memory_initialization_radix=16;
memory_initialization_vector=00000827 0001102b 00421820 00622020 00832820 00a33020 00463804 00a64820 01264004
00284826 01215020 01075822 00e86022 012c6824 012c7025 00c77825 00c78027 00e38820 02289004 02239804 00f3a004
0281a820 0255b025 0296b820 0296c022 02d4c822 0241d026 02d4d82b 0354e02b 02c2e820 0282f022 017af820;
Friendly reminder: If the rst is not pulled high first, the first instruction will not be fetched. A friend of mine wrote this for an afternoon and reconstructed it for a long time; according to my personal analysis, it is because of the rising edge of clk Arrived, but the PC address is not ready yet, resulting in the first instruction not being fetched