module TOP(
input clk,
output [3:0] sel_r,
output [3:0] sel_l,
output [7:0] seg_r,
output [7:0] seg_l
);
wire [31:0] result;
wire clk_1ms,clk_1s;
CPU cpu_0(
.clk(clk),
.clk_1s(clk_1s),
.res(result)
);
clk_div clk_0(
.clk(clk),
.clk_1ms(clk_1ms),
.clk_1s(clk_1s)
);
display dis_0(
.clk_1ms(clk_1ms),
.din(result),
.sel_l(sel_l),
.sel_r(sel_r),
.seg_l(seg_l),
.seg_r(seg_r)
);
endmodule
`timescale 1ns / 1ps
module CPU(
input clk,
input clk_1s,
output [31:0] res
);
wire MtoR,MemW,Beq,Bne,ALUSrc,RegW,RegDst,Halt,ImmExtSel,J;
wire branch;
wire [3:0] ALU_OP;
wire [31:0] cs_RD,ds_RD;
wire [31:0] R1,R2;
wire [31:0] sign_imm,zero_imm,ImmExt;
wire Eq;
wire [31:0] ALU_0_R,ALU_1_R,ALU_2_R,j_target;
wire [31:0] pc_out;
wire [9:0] c_out;
CU cu_0(.OPC (cs_RD[31:26]),
.FUNC (cs_RD[5:0]),
.MtoR (MtoR ),
.MemW (MemW ),
.Beq (Beq ),
.Bne (Bne ),
.ALU_OP (ALU_OP),
.ALUSrc (ALUSrc),
.RegW (RegW ),
.RegDst (RegDst),
.Halt (Halt ),
.ImmExtSel(ImmExtSel),
.J (J )
);
//------------------------------------------------------------------
CS_dram cs_0(.A(pc_out[11:2]),
.RD(cs_RD)); //组合电路
GR gr_0(.CLK(clk),
.R1A(cs_RD[25:21]),
.R2A(cs_RD[20:16]),
.WA(RegDst?cs_RD[15:11]:cs_RD[20:16]),
.WD(MtoR?ds_RD:ALU_0_R),
.WE(RegW),
.R1(R1),
.R2(R2)); //读组合,写时序
DS_dram ds_0(.CLK(clk),
.A(Halt?c_out:ALU_0_R[11:2]),
.RD(ds_RD),
.WD(R2),
.WE(MemW)); //读组合,写时序;c_out=80h..87h
//--------------------------------------------
assign branch=(Beq & Eq) | (Bne & ~Eq);
assign j_target={pc_out[31:28],cs_RD[25:0]<<2};
wire [31:0] pc_next = J ? j_target : (branch ? ALU_2_R : ALU_1_R);
PC pc_0(.clk(clk),
.EN(~Halt),
.din(pc_next),
.dout(pc_out));
//-------------------------------------------------
ALU alu_0(.X(R1),
.Y(ALUSrc?ImmExt:R2),
.OPR(ALU_OP),
.Equal(Eq),
.Result(ALU_0_R));
ALU alu_1(.X(pc_out),
.Y(32'h0000_0004),
.OPR(4'h5),
.Result(ALU_1_R)); //可以改成assign实现PC=PC+4
//可以改成assign实现PC=PC+4
assign sign_imm={{16{cs_RD[15]}},cs_RD[15:0]};
assign zero_imm={16'd0,cs_RD[15:0]};
assign ImmExt=(ImmExtSel == 0)?sign_imm:zero_imm;
ALU alu_2(.X(ImmExt<<2),
.Y(ALU_1_R),
.OPR(4'h5),
.Result(ALU_2_R)); //可以改成assign BRANCH=PC+4+IMM<<2
//------------------------------------------------------
count c_0(.clk(Halt?clk_1s:1'b0), //clk_1s,输出80h..87h
.dout(c_out));
assign res=Halt?ds_RD:32'h0000_0000;
endmodule
`timescale 1ns / 1ps
module CU(
input [5:0] OPC, // 操作码
input [5:0] FUNC, // 功能码
output reg MtoR, // 存储器到寄存器
output reg MemW, // 存储器写
output reg Beq, // 相等分支
output reg Bne, // 不等分支
output reg [3:0] ALU_OP, // ALU操作
output reg ALUSrc, // ALU源选择
output reg RegW, // 寄存器写
output reg RegDst, // 寄存器目标选择
output reg Halt, // 停机
output reg ImmExtSel, //用于控制立即数符号扩展还是零扩展
output reg J
);
always @(*)begin
case(OPC)
6'd0:begin
case(FUNC)
6'd32:begin ALU_OP=4'b0101;{MtoR,MemW,Beq,Bne,ALUSrc,RegW,RegDst,Halt,ImmExtSel,J}=10'b0000_0110_00; end // R型指令: ADD
6'd34:begin ALU_OP=4'b0110;{MtoR,MemW,Beq,Bne,ALUSrc,RegW,RegDst,Halt,ImmExtSel,J}=10'b0000_0110_00; end // R型指令: SUB(新增)
6'd42:begin ALU_OP=4'b1011;{MtoR,MemW,Beq,Bne,ALUSrc,RegW,RegDst,Halt,ImmExtSel,J}=10'b0000_0110_00;end // R型指令: SLT
6'd12:begin{MtoR,MemW,Beq,Bne,ALUSrc,RegW,RegDst,Halt,ImmExtSel,J}=10'b0000_0001_00;end // 停机指令
default:begin {MtoR,MemW,Beq,Bne,ALUSrc,RegW,RegDst,Halt,ImmExtSel,J}=10'b0000_0000_00; end
endcase
end
6'd4:begin {MtoR,MemW,Beq,Bne,ALUSrc,RegW,RegDst,Halt,ImmExtSel,J}=10'b0010_0000_00; end // I型指令: BEQ
6'd5:begin {MtoR,MemW,Beq,Bne,ALUSrc,RegW,RegDst,Halt,ImmExtSel,J}=10'b0001_0000_00;end // I型指令: BNE
6'd8:begin ALU_OP=4'b0101; {MtoR,MemW,Beq,Bne,ALUSrc,RegW,RegDst,Halt,ImmExtSel,J}=10'b0000_1100_00;end // I型指令: ADDI
6'd13:begin ALU_OP=4'b1000;{MtoR,MemW,Beq,Bne,ALUSrc,RegW,RegDst,Halt,ImmExtSel,J}=10'b0000_1100_10;end // I型指令: ORI(新增)
6'd15:begin ALU_OP=4'b0000;{MtoR,MemW,Beq,Bne,ALUSrc,RegW,RegDst,Halt,ImmExtSel,J}=10'b0000_1100_10;end // I型指令: LUI(新增)
6'd35:begin ALU_OP=4'b0101;{MtoR,MemW,Beq,Bne,ALUSrc,RegW,RegDst,Halt,ImmExtSel,J}=10'b1000_1100_00;end // I型指令: LW
6'd43:begin ALU_OP=4'b0101;{MtoR,MemW,Beq,Bne,ALUSrc,RegW,RegDst,Halt,ImmExtSel,J}=10'b0100_1000_00; end // I型指令: SW
6'd2:begin {MtoR,MemW,Beq,Bne,ALUSrc,RegW,RegDst,Halt,ImmExtSel,J}=10'b0000_0110_01; ALU_OP = 4'b0101; end // J型指令: JAL(新增)
default: begin
{MtoR,MemW,Beq,Bne,ALUSrc,RegW,RegDst,Halt,ImmExtSel,J}=10'b0000_0000_00;
end
endcase
end
endmodule
module CS_dram(
input [11:2] A,
output [31:0] RD
);
dist_mem_gen_0 u1(.a(A),.spo(RD));
endmodule
module GR(
input [4:0] R1A, R2A, WA,
input WE,
input [31:0] WD,
input CLK,
output reg [31:0] R1, R2
);
reg [31:0] rf [31:0]; // 32个32位寄存器
always @(posedge CLK) begin
if (WE && WA != 0) rf[WA] <= WD;
end
always @(*) begin
R1 = (R1A == 0) ? 0 : rf[R1A]; // 组合逻辑读取
R2 = (R2A == 0) ? 0 : rf[R2A];
end
endmodule
module DS_dram(
input CLK,
input [9:0] A,
input WE,
input [31:0] WD,
output [31:0] RD
);
DS_1 u1(.clk(CLK),
.a(A),
.d(WD),
.we(WE),
.spo(RD)
);
endmodule
module PC(
input clk,
input EN,
input [31:0] din,
output reg [31:0]dout=32'h0000_0000
);
always @(posedge clk) begin
if(EN) dout<=din;
end
endmodule
module ALU(
input [31:0] X,Y,
input [3:0] OPR,
output reg [31:0] Result,Result2,
output reg OF,
output reg UOF,
output reg Equal
);
reg [32:0] temp;
always @(*) begin
Result=32'b0;
Result2=32'b0;
OF=0;
UOF=0;
Equal=(X==Y);
case(OPR)
4'd0:begin Result=X<<Y[4:0]; end
4'd1:begin Result=X>>>Y[4:0]; end
4'd2:begin Result=X>>Y[4:0]; end
4'd3:begin {Result2,Result}=X*Y; end
4'd4:begin Result=X/Y; Result2=X%Y; end
4'd5:begin
temp=X+Y;
Result=temp[31:0];
OF=(X[31]==Y[31])&&(Result[31]!=X[31]);
UOF=temp[32];
end
4'd6:begin
Result=X-Y;
OF=(X[31]!=Y[31])&&(Result[31]==X[31]);
UOF=(X<Y);
end
4'd7:begin Result=X&Y; end
4'd8:begin Result=X|Y; end
4'd9:begin Result=X^Y; end
4'd10:begin Result=~(X|Y); end
4'd11:begin
if(X[31]!=Y[31])Result=X[31];
else Result=(X<Y);
end
4'd12:begin Result=(X<Y)?1:0; end
default: begin
Result = 32'd0;
Result2 = 32'd0;
OF = 1'b0;
UOF = 1'b0;
end
endcase
end
endmodule
module count(
input clk,
output reg [9:0] dout = 10'd128 // 初始化为128
);
always @(posedge clk) begin
if (dout < 10'd135) dout <= dout + 1;
else dout <= 10'd128;
end
endmodule
`timescale 1ns / 1ps
module clk_div(
input clk,
output reg clk_1s=1'b0,
output reg clk_100ms=1'b0,
output reg clk_1ms=1'b0
);
//clk_100ms
reg [22:0] cnt_100ms=23'b0;
always @(posedge clk)begin
if(cnt_100ms<=23'd4999999)begin
cnt_100ms<=cnt_100ms+1;
clk_100ms<=clk_100ms;
end
else begin
cnt_100ms<=23'b0;
clk_100ms<=~clk_100ms;
end
end
//clk_1s
reg [25:0] cnt_1s=26'b0;
always @(posedge clk)begin
if(cnt_1s<=26'd49999999)begin
cnt_1s<=cnt_1s+1;
clk_1s<=clk_1s;
end
else begin
cnt_1s<=26'b0;
clk_1s<=~clk_1s;
end
end
//clk_1ms
reg [22:0] cnt_1ms=23'b0;
always @(posedge clk)begin
if(cnt_1ms<=23'd49999)begin
cnt_1ms<=cnt_1ms+1;
clk_1ms<=clk_1ms;
end
else begin
cnt_1ms<=23'b0;
clk_1ms<=~clk_1ms;
end
end
endmodule
module seg7(
input wire [3 : 0] din ,
output reg [6 : 0] dout
);
always @(*) begin
case(din)
4'b0000: dout = 7'h3f;
4'b0001: dout = 7'h06;
4'b0010: dout = 7'h5b;
4'b0011: dout = 7'h4f;
4'b0100: dout = 7'h66;
4'b0101: dout = 7'h6d;
4'b0110: dout = 7'h7d;
4'b0111: dout = 7'h07;
4'b1000: dout = 7'h7f;
4'b1001: dout = 7'h6f;
4'b1010: dout = 7'h77;
4'b1011: dout = 7'h7c;
4'b1100: dout = 7'h39;
4'b1101: dout = 7'h5e;
4'b1110: dout = 7'h79;
4'b1111: dout = 7'h71;
endcase
end
endmodule
// 数码管显示控制器(保持不变)
module display(
input wire clk_1ms , //1000HZ时钟信号
input wire [31:0] din ,
output wire [3 : 0] sel_l , // 左组, 通过 l 区分
output wire [3 : 0] sel_r , // 右组, 通过 r 区分
output wire [7 : 0] seg_l , // 左组, 通过 l 区分
output wire [7 : 0] seg_r // 右组, 通过 r 区分
);
reg [3:0] shift = 4'b0001; // 用于转换工作的数码管
always @(posedge clk_1ms)begin
shift <= {shift[2:0], shift[3]};
end
wire [6:0] x1, x2, x3, x4; //表示{1-4}数码管所要显示数字对应的输出信号
wire [6:0] x5, x6, x7, x8; //表示{5-8}数码管所要显示数字对应的输出信号
// right group
seg7 U1(.din(din[3 : 0]), .dout(x1)); // 右起第一个, 最低4位
seg7 U2(.din(din[7 : 4]), .dout(x2));
seg7 U3(.din(din[11: 8]), .dout(x3));
seg7 U4(.din(din[15:12]), .dout(x4));
//将din的各四位送入显示译码模块,输出为Xn
// left group
seg7 U5(.din(din[19:16]), .dout(x5));
seg7 U6(.din(din[23:20]), .dout(x6));
seg7 U7(.din(din[27:24]), .dout(x7));
seg7 U8(.din(din[31:28]), .dout(x8)); // 左起第一个, 最高4位
assign sel_r = shift & 4'b1111; // 通过按位与操作点亮指定数码管
assign sel_l = shift & 4'b1111; // 通过按位与操作点亮指定数码管
assign seg_r = (shift == 4'b0001)? x1 :
(shift == 4'b0010)? x2 :
(shift == 4'b0100)? x3 :
(shift == 4'b1000)? x4 : 0;
assign seg_l = (shift == 4'b0001)? x5 :
(shift == 4'b0010)? x6 :
(shift == 4'b0100)? x7 :
(shift == 4'b1000)? x8 : 0;
endmodule为什么不对
最新发布