Skip to content

Instantly share code, notes, and snippets.

@LuvLetter
Last active June 1, 2017 13:28
Show Gist options
  • Save LuvLetter/c26b4a4e53ab711d8e3e96c3b188c1fe to your computer and use it in GitHub Desktop.
Save LuvLetter/c26b4a4e53ab711d8e3e96c3b188c1fe to your computer and use it in GitHub Desktop.
counter
module CPU_monitor(
input clk,
input rst,
input [1:0] SW,
);
wire clk;
wire [31:0] ALU_F;
R_CPU My_CPU(
.clk(clk),
.rst(rst),
.ALU_F(ALU_F)
);
always @(*)
begin
case (SW[1:0])
2'b00: LED = ALU_F[7:0];
2'b01: LED = ALU_F[15:8];
2'b10: LED = ALU_F[23:16];
2'b11: LED = ALU_F[31:24];
endcase
end
endmodule
module R_CPU(
input clk,
input rst,
output [31:0] ALU_F //为显示指令运算结果用
);
wire [31:0] Inst_code;
wire [31:0] PC_out;
wire [4:0] Rs,Rt,Rd;
wire [5:0] OP,func;
wire [31:0] ALU_A,ALU_B;
reg Write_Reg;
wire ZF,OF;
reg FR_ZF,FR_OF;
reg [2:0] ALU_OP;
IF_M My_IF(
.clk(clk),
.rst(rst),
.Inst_code(Inst_code)
.PC_out(PC_out)
);
assign OP = Inst_code[31:26];
assign Rs = Inst_code[25:21];
assign Rt = Inst_code[20:16];
assign Rd = Inst_code[15:11];
assign func = Inst_code[5:0];
REGS My_REG(
.Clk(~clk),
.Reset(rst),
.R_Addr_A(Rs),
.R_Addr_B(Rt),
.W_Addr(Rd),
.W_Data(ALU_F),
.Write_Reg(Write_Reg),
.R_Data_A(ALU_A),
.R_Data_B(ALU_B)
);
ALU My_ALU(
.A(ALU_A),
.B(ALU_B),
.ALU_OP(ALU_OP),
.F(ALU_F),
.ZF(ZF),
.OF(OF)
);
always @(*)
begin
ALU_OP = 3'b000;
Write_Reg = 1'b0;
if (OP==6'b000000)
begin
Write_Reg = 1'b1;
case (func)
6'b100000: ALU_OP = 3'b100;
6'b100010: ALU_OP = 3'b101;
6'b100100: ALU_OP = 3'b000;
6'b100101: ALU_OP = 3'b001;
6'b100110: ALU_OP = 3'b010;
6'b100111: ALU_OP = 3'b011;
6'b101011: ALU_OP = 3'b110;
6'b000100: ALU_OP = 3'b111;
default: ALU_OP = 3'b000;
endcase
end
else ALU_OP = 3'b000;
end
always @(negedge clk)
begin
FR_ZF <= ZF;
FR_OF <= OF;
end
endmodule
module IF_M(
input clk,
input rst,
output [31:0] Inst_code
output [31:0] PC_out
);
reg [31:0] PC;
wire [31:0] PC_new;
ROM_B Inst_ROM (
.clka(clk),
.addra(PC[7:2]),
.douta(Inst_code)
);
assign PC_new = PC + 4;
assign PC_out = {24'b0,PC[7:0]};
always @(negedge clk or posedge rst)
begin
if (rst)
PC <= 32'h0000_0000;
else
PC <= PC_new;
end
endmodule
module REGS(
input Clk,
input Reset,
input [4:0] R_Addr_A,
input [4:0] R_Addr_B,
input [4:0] W_Addr,
input [31:0] W_Data,
input Write_Reg,
output [31:0] R_Data_A,
output [31:0] R_Data_B
);
reg [31:0] REG_Files[1:31];
integer i;
assign R_Data_A = (R_Addr_A==5'b00000)? 32'h0000_0000 : REG_Files[R_Addr_A];
assign R_Data_B = (R_Addr_B==5'b00000)? 32'h0000_0000 : REG_Files[R_Addr_B];
always @(posedge Clk or posedge Reset)
begin
if(Reset) begin
for(i=1;i<=31;i=i+1)
REG_Files[i]<= 32'h0000_0000;
end
else begin
if ((Write_Reg) &&(W_Addr != 5'b00000))
REG_Files[W_Addr] <= W_Data;
end
end
endmodule
module ALU(
input [31:0] A,
input [31:0] B,
input [2:0] ALU_OP,
output reg [31:0] F,
output ZF,
output OF
);
parameter Zero_32 = 32'h0000_0000, One_32 = 32'h0000_0001;
reg C32;
always @(*)
begin
C32 = 1'b0;
case (ALU_OP)
3'b000:F = A & B;
3'b001:F = A | B;
3'b010:F = A ^ B;
3'b011:F = ~(A | B);
3'b100:{C32,F} = A + B;
3'b101:{C32,F} = A - B;
3'b110:F = (A < B) ? One_32:Zero_32;3'b111:F = B << A;
default:F= Zero_32;
endcase
end
assign ZF = (F == Zero_32)?1'b1:1'b0;
assign OF = ((ALU_OP==3'b100)||(ALU_OP==3'b101))&&(A[31]^B[31]^F[31]^C32);
endmodule
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment