-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCPU_NO_DEBUG.v
178 lines (146 loc) · 6.09 KB
/
CPU_NO_DEBUG.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 17:46:57 11/08/2022
// Design Name:
// Module Name: CPU_NO_DEBUG
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module CPU_NO_DEBUG(clk,rst,r0);
input clk,rst;
output [31:0] r0;
wire [31:0] r1,r2,r3,r4,r5,r31,/***/PC_OUT/***/;
wire [31:0] PC_IN,/***//*PC_OUT,*//***/INSTRUCTION,READ_REG1,READ_REG2,IMM_16BIT_SE/*16 bit immediate sign extended*/,IMM_21BIT_SE/*32 bit immediate sign extended*/,IMM_To_ALU,ALUSrcA,ALUSrcB,ALU_RES,BRANCH_DECN,JUMP_DECN,PC_PLUS_4,OFFSET,PC_PLUS_4_PLUS_OFFSET,REG_WRITE_DATA,MEM_READ_DATA;
wire [4:0] WRITE_REG,SHIFT_AMNT;
/* Control signals*/
wire RegWrite,ImmSel,ALUSrc,CompEnbl,ShiftAmntSel,ShiftEnbl,ShortBr,LongBr,MemRead,MemWrite,BranchReg;
wire [1:0] ALUOp,RegDst,ShiftType,BranchType,JumpType,MemToReg;
wire ALU_RES_ZERO,ALU_RES_MSB,ALU_RES_CARRY,CARRY_FLAG,BRANCH_DECIDE_SEL,JUMP_DECIDE_SEL;
/*control unit update nov 7 21:01*/
control INSTR_DECODER(
.opcode(INSTRUCTION[31:26]),
.func(INSTRUCTION[5:0]),
.reg_dest_sel(RegDst),
.reg_write(RegWrite),
.immediate_sel(ImmSel),
.alu_src_sel(ALUSrc),
.comp_enb(CompEnbl),
.alu_operation_sel(ALUOp),
.shft_type_sel(ShiftType),
.shft_amt_sel(ShiftAmntSel),
.shft_enb(ShiftEnbl),
.branch_type(BranchType),
.short_branch(ShortBr),
.jump_type(JumpType),
.long_branch(LongBr),
.mem_read(MemRead),
.mem_write(MemWrite),
.reg_write_value_sel(MemToReg),
.branch_reg(BranchReg)
);
/**/
/*control signals*/
/*
input RegWrite,ImmSel,ALUSrc,CompEnbl,ShiftAmntSel,ShiftEnbl,ShortBr,LongBr,MemRead,MemWrite,BranchReg;
input [1:0] ALUOp,RegDst,ShiftType,BranchType,JumpType,MemToReg;
*/
/**/
/***/
wire [11:0] I_CACHE_ADDR_IN;
/***/
/* Program Counter */
Register PC(.D(PC_IN),.clk(clk),.rst(rst),.RegWrEnbl(1'b1),.Q(PC_OUT));
/***/
MUX_2to1 #(.WIDTH(12)) I_CACHE_ADDR_SELECTOR_MUX(.in0(PC_IN[11:0]),.in1(12'd0),.out(I_CACHE_ADDR_IN),.sel(rst));
/***/
/* Instruction Cache */
READ_ONLY_MEM I_CACHE (
.clka(clk), // input clka
.addra(/*PC_OUT[11:0]*//***/I_CACHE_ADDR_IN/***/), // input [11 : 0] addra
.douta(INSTRUCTION) // output [31 : 0] douta
);
/* Register file write selector MUX */
MUX_4to1 #(.WIDTH(5)) REGISTER_WRITE_SELECTOR_MUX(.in0(INSTRUCTION[25:21]),.in1(INSTRUCTION[20:16]),.in2(5'b11111),.in3(/*DONT CARE*/5'b00000),.out(WRITE_REG),.sel(RegDst));
/* Register file */
RegFile REG_FILE(.clk(clk),.rst(rst),.rsAdd(INSTRUCTION[25:21]),.rtAdd(INSTRUCTION[20:16]),.wrAdd(WRITE_REG),.wrData(REG_WRITE_DATA),.wrEnable(RegWrite),.rsOut(READ_REG1),.rtOut(READ_REG2),/**/.r0(r0),.r1(r1),.r2(r2),.r3(r3),.r4(r4),.r5(r5),.r31(r31)/**/);
/* regfile remaining wires: write data */
/* Immdiate field sign extender modules */
SIGN_EXTND IMM_SE_16(.in(INSTRUCTION[15:0]),.out(IMM_16BIT_SE));
SIGN_EXTND #(.INPUT_WIDTH(21)) IMM_SE_21(.in(INSTRUCTION[20:0]),.out(IMM_21BIT_SE));
/* Immediate selector MUX*/
MUX_2to1 IMM_SELECTOR_MUX(.in0(IMM_21BIT_SE),.in1(IMM_16BIT_SE),.out(IMM_To_ALU),.sel(ImmSel));
/* ALU source B selector MUX */
MUX_2to1 ALUsrcB_SELECTOR_MUX(.in0(READ_REG2),.in1(IMM_To_ALU),.out(ALUSrcB),.sel(ALUSrc));
/* ALU source A selector MUX */
MUX_2to1 ALUsrcA_SELECTOR_MUX(.in0(READ_REG1),.in1(32'd0),.out(ALUSrcA),.sel(CompEnbl));
/* ALU shift amount selector MUX */
MUX_2to1 #(.WIDTH(5)) ALUshiftamnt_SELECTOR_MUX(.in0(INSTRUCTION[10:6]/*shamt*/),.in1(READ_REG2[4:0]),.out(SHIFT_AMNT),.sel(ShiftAmntSel));
/* main ALU */
ALU_32bit ALUmain(
.a(ALUSrcA),
.b(ALUSrcB),
.AddrSrcBSel(CompEnbl),
.PrimaryOutputSel(ALUOp),/*ALUOp*/
.ShifterInputSel(ShiftEnbl),
.ShiftTypeALU(ShiftType),
.ShiftAmntALU(SHIFT_AMNT),
.ShifterEnblALU(ShiftEnbl),
.ALUOut(ALU_RES),
.ALUc_out(ALU_RES_CARRY),
.MSB(ALU_RES_MSB),
.ALUzero(ALU_RES_ZERO)
);
/* Data memory */
/*
READ_WRITE_MEM DATA_MEM (
.clka(~clk), // input clka
.ena(1'b1), // input ena
.wea(MemWrite), // input [0 : 0] wea
.addra(ALU_RES[12:0]), // input [12 : 0] addra
.dina(READ_REG2), // input [31 : 0] dina
.douta(MEM_READ_DATA) // output [31 : 0] douta
);
*/
READ_WRITE_MEM DATA_MEM (
.clka(~clk), // input clka
.ena(1'b1), // input ena
.wea(MemWrite), // input [0 : 0] wea
.addra(ALU_RES[9:0]), // input [9 : 0] addra
.dina(READ_REG2), // input [31 : 0] dina
.douta(MEM_READ_DATA) // output [31 : 0] douta
);
/* carry flip flop */
Register #(.WIDTH(1)) CARRY_FF(.D(ALU_RES_CARRY),.clk(clk),.rst(rst),.RegWrEnbl(1'd1),.Q(CARRY_FLAG));
/* branch decider */
BranchDecider BRANCH_DECIDE(.zero(ALU_RES_ZERO),.MSB(ALU_RES_MSB),.ShortBr(ShortBr),.ShortBrType(BranchType),.ShortBr_out(BRANCH_DECIDE_SEL));
/* branch decider selectot MUX */
MUX_2to1 BRANCH_DECIDE_SELECTOR_MUX(.in0(PC_PLUS_4),.in1(PC_PLUS_4_PLUS_OFFSET),.out(BRANCH_DECN),.sel(BRANCH_DECIDE_SEL));
/* jump decider */
JumpDecider JUMP_DECIDE(.carry(CARRY_FLAG),.LongBr(LongBr),.LongBrType(JumpType),.LongBr_out(JUMP_DECIDE_SEL));
/* jump decider selector MUX */
/* long jump address = concat(PC[31:26],INSTRUCTION[25:0])*/
/* note that instruction memory is word addressed hence PC+4 is actually PC+1 and offsets/addresses are not multiples of 4, hence sign extension is not required */
MUX_2to1 JUMP_DECIDER_SELECTOR_MUX(.in0(BRANCH_DECN),.in1({PC_OUT[31:26],INSTRUCTION[25:0]}),.out(JUMP_DECN),.sel(JUMP_DECIDE_SEL));
/* branch register selector MUX */
MUX_2to1 BRANCH_REG_SELECTOR_MUX(.in0(JUMP_DECN),.in1(READ_REG1),.out(PC_IN),.sel(BranchReg));
/* pc + 1 adder */
ADDR_32bit PC_ADDR1(.a(32'd1),.b(PC_OUT),.c_in(1'd0),.ADDRout(PC_PLUS_4),.ADDRc_out());
/* offset sign extender */
SIGN_EXTND OFFSET_SIGN_EXTEND(.in(INSTRUCTION[15:0]),.out(OFFSET));
/* pc +1 + offset adder*/
ADDR_32bit PC_ADDR2(.a(PC_PLUS_4),.b(OFFSET),.c_in(1'd0),.ADDRout(PC_PLUS_4_PLUS_OFFSET),.ADDRc_out());
/* reg write data selector mux */
MUX_4to1 REG_WRITE_DATA_SELECTOR_MUX(.in0(ALU_RES),.in1(MEM_READ_DATA),.in2(PC_PLUS_4),.in3(32'd0/*dummy line*/),.out(REG_WRITE_DATA),.sel(MemToReg));
endmodule