-
Notifications
You must be signed in to change notification settings - Fork 4
/
core.v
249 lines (212 loc) · 8.7 KB
/
core.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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
`default_nettype none
`timescale 1ns/1ps
`ifdef CUSTOM_DEFINE
`include "../defines.vh"
`endif
`include "core_control_unit.v"
`include "core_program_counter.v"
`include "core_regfile.v"
`include "core_execution_unit/core_execution_unit.v"
`include "core_csr_unit/core_csr_unit.v"
`define RAM_MUX_CORE
module corep
`ifdef CUSTOM_DEFINE
#(parameter MEM_ADDR_WIDTH = `MEM_ADDR_WIDTH,
parameter DATA_WIDTH = `REG_DATA_WIDTH,
parameter TRANSFER_WIDTH = `MEM_TRANSFER_WIDTH,
parameter CSR_OP_WIDTH = `CSR_OP_WIDTH,
parameter CSR_ADDR_WIDTH = `CSR_ADDR_WIDTH,
parameter ALU_OP_WIDTH = `ALU_OP_WIDTH,
parameter LIS_OP_WIDTH = `LIS_OP_WIDTH,
parameter BR_OP_WIDTH = `BR_OP_WIDTH,
parameter DATA_ORIGIN_WIDTH = `DATA_ORIGIN_WIDTH,
parameter REG_ADDR_WIDTH = `REG_ADDR_WIDTH)
`else
#(parameter MEM_ADDR_WIDTH = 10,
parameter DATA_WIDTH = 32,
parameter TRANSFER_WIDTH = 4,
parameter CSR_OP_WIDTH = 3, // 3
parameter CSR_ADDR_WIDTH = 12,
parameter ALU_OP_WIDTH = 4,
parameter LIS_OP_WIDTH = 3,
parameter BR_OP_WIDTH = 2,
parameter DATA_ORIGIN_WIDTH = 2,
parameter REG_ADDR_WIDTH = 5)
`endif
(
clk,
rst_n,
we_mem_data_o,
addr_mem_data_o,
val_mem_data_read_i,
val_mem_data_write_o,
req_mem_data_o, // Request to make actiopn
gnt_mem_data_i, // Action Granted
rvalid_mem_data_i, // Valid when write is ok
addr_mem_prog_o,
val_mem_prog_i,
req_mem_prog_o, // Request to make actiopn
gnt_mem_prog_i, // Action Granted
write_transfer_mem_data_o
);
localparam DATA_TARGET_WIDTH = 2;
input clk;
input rst_n;
output we_mem_data_o;
output [MEM_ADDR_WIDTH-1 : 0] addr_mem_data_o;
input [DATA_WIDTH-1 : 0] val_mem_data_read_i;
output [DATA_WIDTH-1 : 0] val_mem_data_write_o;
output req_mem_data_o; // Request to make actiopn
input gnt_mem_data_i; // Action Granted
input rvalid_mem_data_i; // Valid when write is ok // Write valid signal (OK to increase PC)
output [MEM_ADDR_WIDTH-1 : 0] addr_mem_prog_o;
input [DATA_WIDTH-1 : 0] val_mem_prog_i;
output req_mem_prog_o; // Request to make actiopn
input gnt_mem_prog_i; // Action Granted
output [TRANSFER_WIDTH-1:0] write_transfer_mem_data_o;
wire is_stall_t;
wire is_load_store;
//wire we_dataMem;
//wire oe_DataMem;
//wire[ADDR_WIDTH-1 : 0] addr_DataMem;
//wire[DATA_WIDTH-1 : 0] data_DataMem;
//wire oe_progmem;
//wire[DATA_WIDTH-1 : 0] instruction_progmem;
//wire[ADDR_WIDTH-1 : 0] addr_progMem;
wire [ALU_OP_WIDTH-1:0] ALU_op_t;
wire [LIS_OP_WIDTH-1:0] LIS_op_t;
wire [BR_OP_WIDTH-1:0] BR_op_t;
wire [DATA_ORIGIN_WIDTH-1:0] data_origin_t;
wire [DATA_TARGET_WIDTH-1:0] data_target_t;
wire is_load_store_t;
wire is_branch_t;
wire is_absolute_t;
wire is_conditional_t;
//wire mem_w_t;
//wire mem_to_reg_t;
//wire reg_r_t;
wire [REG_ADDR_WIDTH-1:0] r1_addr_t;
wire [REG_ADDR_WIDTH-1:0] r2_addr_t;
wire [REG_ADDR_WIDTH-1:0] reg_addr_t;
wire [DATA_WIDTH-1:0] imm_val_t;
wire we_reg_file;
wire [REG_ADDR_WIDTH-1:0] r1_num_read_reg_file;
wire [REG_ADDR_WIDTH-1:0] r2_num_read_reg_file;
wire [REG_ADDR_WIDTH-1:0] r_num_write_reg_file;
wire [DATA_WIDTH-1:0] data_in_reg_file;
// Outputs
wire [DATA_WIDTH-1:0] rs1_reg_file;
wire [DATA_WIDTH-1:0] rs2_reg_file;
wire [DATA_WIDTH-1 : 0] pc;
wire [DATA_WIDTH-1 : 0] new_pc;
wire [DATA_WIDTH-1 : 0] reg_pc;
wire [CSR_ADDR_WIDTH-1 : 0]csr_addr_t;
wire [CSR_OP_WIDTH-1 : 0] csr_op_t;
wire [DATA_WIDTH-1 : 0] csr_val_r;
wire [DATA_WIDTH-1 : 0] csr_val_w;
reg req_mem_data_o;
wire req_mem_data_o_intern;
reg req_mem_prog_o;
wire req_mem_prog_o_intern;
reg load_wait; // Slave returns the requested data on the rdata line, exactly one cycle after the grant.
wire load_wait_intern; // Slave returns the requested data on the rdata line, exactly one cycle after the grant.
assign addr_mem_prog_o = pc[MEM_ADDR_WIDTH-1:0]; // Assign lower bits of PC to prog ADDR
controlUnit controlUnit_inst(
.instruction (val_mem_prog_i), // Instruction from prog mem input
.ALU_op (ALU_op_t), // ALU operation output
.LIS_op (LIS_op_t), // Load Store Operation output
.BR_op_o (BR_op_t), // Branch operation output
.csr_op_o(csr_op_t), // CSR OP
.data_origin_o (data_origin_t), // Data origin output (Rs2 or imm or pc)
.data_target_o (data_target_t), // Data target output (ALU or LIS or PC4 or CSR)
.is_branch_o (is_branch_t), // Branch indicator output
.is_conditional_o (is_conditional_t), // Conditional branch indicator
.is_load_store (is_load_store_t), // execution_unit
.mem_w (we_mem_data_o), // LoadStore indicator output
.reg_w (we_reg_file), // RegFile write enable
.r1_addr (r1_num_read_reg_file), // RS1 addr
.r2_addr (r2_num_read_reg_file), // RS2 addr
.reg_addr (r_num_write_reg_file), // RD addr
.imm_val_o (imm_val_t), //execution unit imm val
.write_transfer_o (write_transfer_mem_data_o),
.csr_addr_o(csr_addr_t),
.csr_data_o(csr_val_w), // CSR Val Out WRITE
.is_stall_o(is_stall_t),
.mem_req_o(req_mem_data_o_intern), // Request to make actiopn
.mem_gnt_i(gnt_mem_data_i), // Action Granted //, wait until rvalid or cycle
.mem_rvalid_i(rvalid_mem_data_i), // Valid when write is ok // Write valid signal (OK to increase PC)
.load_wait_i(load_wait),
.load_wait_o(load_wait_intern)
);
programCounter program_counter_inst (
.rst_n (rst_n),
.clk (clk),
//.is_branch_i (is_branch_t), // Branch indicator
//.is_absolute_i (is_absolute_t), // Absolute or relative branch
.is_stall_i(is_stall_t), // Stall the PC
.new_pc_i (new_pc), // new pc or offset
.reg_pc_o (reg_pc),
.pc (pc), // next addr
.req_mem_prog_o(req_mem_prog_o_intern), // Request to make actiopn
.gnt_mem_prog_i(gnt_mem_prog_i) // Action Granted
);
regFile reg_file_inst(
.rst_n (rst_n) , // Reset Neg
.clk (clk) , // Clock
.we (we_reg_file) , // Write Enable
.r1_num_read (r1_num_read_reg_file) , // Address of r1 Read
.r2_num_read (r2_num_read_reg_file) , // Address of r2 Read
.r_num_write (r_num_write_reg_file), // Addres of Write Register
.data_in (data_in_reg_file) , // Data to write
.rs1 (rs1_reg_file) , // Output register 1
.rs2 (rs2_reg_file) // Output register 2
);
executionUnit exec_unit_inst(
.ALU_op (ALU_op_t), // ALU operation input
.LIS_op (LIS_op_t), // Load Store Operation input
.BR_op (BR_op_t), // Branch operation input
.csr_op_i(csr_op_t),
.data_origin_i(data_origin_t), // Data origin input (Rs2 or imm or pc)
.data_target_i(data_target_t),
.rs1_i (rs1_reg_file), // RS1
.rs2_i (rs2_reg_file), // RS2
.imm_val_i (imm_val_t), // immidiate value
.d_o (data_in_reg_file), // output data to data_in_reg_file),
.val_mem_data_write_o (val_mem_data_write_o), // output to data mem
.val_mem_data_read_i (val_mem_data_read_i), // input from data mem
.addr_mem_data_o (addr_mem_data_o), // output address to data mem
.is_branch_i (is_branch_t), // Branch indicator input
.is_loadstore (is_load_store_t), // LoadStore indicator input
.new_pc_offset_o (new_pc), // new offset or new pc
.reg_pc_i (reg_pc), // Actual PC
.pc_i(pc),
.is_conditional_i (is_conditional_t), // Rewrite the current value to PC
.csr_val_i(csr_val_r) // CSR Val in READ
//.csr_val_o(csr_val_w) // CSR Val Out WRITE
);
crs_unit crs_unit_inst(
.rst_n(rst_n),
.clk(clk),
.csr_addr_i(csr_addr_t), // Adr
.csr_val_i(csr_val_w), // Val in
.csr_val_o(csr_val_r), // Val Out
.csr_op_i(csr_op_t) // Op In
);
// Register the memory requests
always @ (posedge clk or negedge rst_n) begin
req_mem_data_o <= 1'b0;
req_mem_prog_o <= 1'b0;
load_wait <= 1'b0;
if (!rst_n) begin
req_mem_data_o <= 1'b0;
req_mem_prog_o <= 1'b0;
load_wait <= 1'b0;
end
else begin
req_mem_data_o <= req_mem_data_o_intern;
req_mem_prog_o <= req_mem_prog_o_intern;
load_wait <= load_wait_intern;
end
end
endmodule
`default_nettype wire