本设计分为10个模块加一个整体仿真激励模块,各模块代码如下:
流水灯的变换形式为: 0000000 -> 00000001 -> 00000011 -> 00000111 -> 00001111 -> 00011111 -> 00111111 -> 01111111 -> 11111111
时间间隔为1s。
`timescale 1ns / 1ps
//包括IR
module InsMem(
input CLK,
input InsMemRW, IRWre,
input [31:0] pc_out,
output reg [31:0] ins_out
);
reg [31:0] IDataOut;
reg [7:0] InsMemory[0:255];
initial begin
$readmemb("instructions.txt", InsMemory);
end
always @ (pc_out or InsMemRW) begin
if (InsMemRW) begin
IDataOut[31:24] = InsMemory[pc_out];
IDataOut[23:16] = InsMemory[pc_out+1];
IDataOut[15:8] = InsMemory[pc_out+2];
IDataOut[7:0] = InsMemory[pc_out+3];
end
end
always @ (posedge CLK) begin
if (IRWre)
ins_out <= IDataOut;
end
endmodule
module fp50m(clk,reset,newclk);
input clk,reset;
output newclk;
reg newclk;
reg [31:0] count,count1;
always@(posedge clk or negedge reset)
begin
if(!reset)
begin
newclk<=1'd0;
count<=32'd0;
end
else if(count==32'd1250000) //0.1s 2500000
begin
count<=32'd0;
newclk<=~newclk;
end//end begin
else count<=count+1'd1;
end
endmodule
`timescale 1ns / 1ps
module Extend(
input ExtSel,
input [15:0] Imm_16,
output reg [31:0] Imm
);
always @ (Imm_16 or ExtSel) begin
if (ExtSel) begin
Imm = {
{16{Imm_16[15]}}, Imm_16[15:0]};
end else begin
Imm = {
{16{0}}, Imm_16[15:0]};
end
end
endmodule
`timescale 1ns / 1ps
//包括2选1模块,一个缓冲
module DataMem(
input RD, WR, CLK,
input ALUM2Reg,
input [31:0] alu_out,
input [31:0] result,
input [31:0] reg_out2,
output wire [31:0] data_out
);
reg [31:0] DataOut;
reg [7:0] DataMemory[0:63];
assign data_out = (ALUM2Reg ? DataOut : result);
always @ (alu_out or reg_out2 or RD or WR) begin
if (WR) begin //写入
DataMemory[alu_out] = reg_out2[31:24];
DataMemory[alu_out+1] = reg_out2[23:16];
DataMemory[alu_out+2] = reg_out2[15:8];
DataMemory[alu_out+3] = reg_out2[7:0];
end else begin //读出
DataOut[31:24] = DataMemory[alu_out];
DataOut[23:16] = DataMemory[alu_out+1];
DataOut[15:8] = DataMemory[alu_out+2];
DataOut[7:0] = DataMemory[alu_out+3];
end
//if (ALUM2Reg) data_out = DataOut;
//else data_out = result;
end
endmodule
`timescale 1ns / 1ps
module ControlUnit(
input CLK, RST,
input zero,
input [5:0] op,
output reg WrRegData, RegWre, ALUSrcA, ALUSrcB, InsMemRW, IRWre, PCWre, RD, WR, ExtSel, ALUM2Reg,
output reg [1:0] RegDst, PCSrc,
output reg [2:0] ALUOp, state
);
reg [2:0] next_state;
parameter [2:0] IF = 3'b000,
ID = 3'b001,
EXE_1 = 3'b110,
EXE_2 = 3'b101,
EXE_3 = 3'b010,
ME