-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathInstructionDecoder.v
116 lines (107 loc) · 3.65 KB
/
InstructionDecoder.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
`include "IDConstants.vh"
module InstructionDecoder(
input [31:0] instr_in,
input [2:0] type,
input [2:0] T_in,
input [2:0] funct3,
input [6:0] opcode,
input [4:0] rs1, rs2, rd,
input carry, zero, lt,
output pc_oe, pc_we, pc_inc, pc_oe2,
output ir_we, mar_we, mar_oe,
output rs1_en, rs2_en, rd_we,
output mem_rw, se_en, se_oe,
output imm_ena, imm_enb, imm_enc,
output funct3_ov, mdb_en, alu_oe,
output [3:0] funct3_val,
output [1:0] mem_size,
output T_rst, branch_taken,
output hlt,
input clk
);
reg [31:0] control_word = 0;
BranchTester bt(
.carry(carry),
.zero(zero),
.lt(lt),
.funct3(funct3),
.taken(branch_taken),
.check(clk & control_word[`PBT])
);
always@ (*)
begin
case (T_in)
3'b000: // fetch
control_word <= `MPC_OE2 | `MMEM_SIZE(3) | `MIR_WE | `MPC_INC;
3'b001:
begin
if (type == 0) control_word <= `MHLT | `MT_RST;
else case (opcode[6:2])
5'b01100: // ALU
control_word <= `MRS1_EN | `MRS2_EN | `MALU_OE | `MRD_WE | `MT_RST;
5'b00100: // ALUI
control_word <= `MRS1_EN | `MIMM_ENB | `MALU_OE | `MRD_WE | `MT_RST;
5'b01101: // LUI
control_word <= `MIMM_ENC | `MRD_WE | `MT_RST;
5'b01000: // STORE
control_word <= `MIMM_ENB | `MRS1_EN | `MALU_OE | `MF3_OV | `MF3_VAL(4'b0000) | `MMAR_WE;
5'b00000: // LOAD
control_word <= `MIMM_ENB | `MRS1_EN | `MALU_OE | `MF3_OV | `MF3_VAL(4'b0000) | `MMAR_WE;
5'b11011: // JAL
if (rd == 5'b0)
control_word <= `MIMM_ENB | `MALU_OE | `MPC_OE | `MPC_WE | `MF3_OV | `MF3_VAL(4'b0000) | `MT_RST;
else control_word <= `MPC_OE | `MRD_WE | `MALU_OE | `MF3_OV | `MF3_VAL(4'b0000) | `MRS2_EN;
5'b11001: // JALR
control_word <= `MPC_OE | `MRD_WE | `MALU_OE | `MRS2_EN;
5'b00101: // AUIPC
control_word <= `MPC_OE | `MIMM_ENB | `MRD_WE;
5'b11000: // BRANCH
control_word <= `MF3_VAL(4'b1000) | `MF3_OV | `MRS1_EN | `MRS2_EN | `MALU_OE | `MBT;
5'b00011: // FENCE
control_word <= `MT_RST;
5'b11100: // ECALL/EBREAK
control_word <= (instr_in[20] ? `MHLT : 0) | `MT_RST;
default: control_word <= `MHLT;
endcase
end
3'b010:
case (opcode[6:2])
5'b01000: // STORE
control_word <= `MMAR_OE | `MMEM_RW | `MRS2_EN | `MMDB_EN | `MMEM_SIZE(funct3[1:0] + 1) | `MT_RST;
5'b00000: // LOAD
control_word <= `MMAR_OE | `MRD_WE | `MSE_OE | (funct3[2] ? 0 : `MSE_EN) | `MMEM_SIZE(funct3[1:0] + 1) | `MT_RST;
5'b11011: // JAL
control_word <= `MIMM_ENB | `MALU_OE | `MPC_OE | `MPC_WE | `MF3_OV | `MF3_VAL(4'b0000) | `MT_RST;
5'b11001: // JALR
control_word <= `MIMM_ENB | `MRS1_EN | `MALU_OE | `MPC_WE | `MT_RST;
5'b11000: // BRANCH
control_word <= (branch_taken ? (`MPC_WE | `MPC_OE | `MIMM_ENB | `MALU_OE | `MF3_OV | `MF3_VAL(4'b0000)) : 0) | `MT_RST;
default: control_word <= `MHLT;
endcase
default: control_word <= `MHLT;
endcase
end
assign pc_oe = control_word[`PPC_OE];
assign pc_we = control_word[`PPC_WE];
assign pc_inc = control_word[`PPC_INC];
assign pc_oe2 = control_word[`PPC_OE2];
assign ir_we = control_word[`PIR_WE];
assign mar_we = control_word[`PMAR_WE];
assign mar_oe = control_word[`PMAR_OE];
assign rs1_en = control_word[`PRS1_EN];
assign rs2_en = control_word[`PRS2_EN];
assign rd_we = control_word[`PRD_WE];
assign mem_rw = control_word[`PMEM_RW];
assign se_en = control_word[`PSE_EN];
assign imm_ena = control_word[`PIMM_ENA];
assign imm_enb = control_word[`PIMM_ENB];
assign imm_enc = control_word[`PIMM_ENC];
assign funct3_ov = control_word[`PF3_OV];
assign mdb_en = control_word[`PMDB_EN];
assign alu_oe = control_word[`PALU_OE];
assign se_oe = control_word[`PSE_OE];
assign funct3_val = control_word[`PF3_VAL];
assign mem_size = control_word[`PMEM_SIZE];
assign hlt = control_word[`PHLT];
assign T_rst = control_word[`PT_RST];
endmodule