Skip to content

Commit 1a8434b

Browse files
committed
Initial HERV implementation
1 parent 15bf532 commit 1a8434b

File tree

9 files changed

+248
-17
lines changed

9 files changed

+248
-17
lines changed

.github/workflows/lint.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ jobs:
77
runs-on: ubuntu-latest
88
strategy:
99
matrix:
10-
width: [1, 4]
10+
width: [1, 4, 8]
1111
name: Linter
1212
env:
1313
REPO : serv

rtl/serv_bufreg.v

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,29 @@ module serv_bufreg #(
8383
wire [2*W+B-2:0] muxdata = {data[W+B-1:0],data_tail};
8484
wire [B:0] muxout = muxdata[{1'b0,shift_amount}+:W];
8585

86+
assign o_lsb = (MDU & i_mdu_op) ? 2'b00 : lsb;
87+
assign o_q = i_en ? muxout : {W{1'b0}};
88+
end else if (W == 8) begin : gen_lsb_w_8
89+
reg [1:0] lsb;
90+
reg [W-2:0] data_tail;
91+
92+
wire [3:0] shift_amount
93+
= !i_shift_op ? 4'd7 :
94+
i_right_shift_op ? (4'd7+{1'b0,i_shamt[2:0]}) :
95+
({1'b0,~i_shamt[2:0]});
96+
97+
always @(posedge i_clk) begin
98+
if (i_en)
99+
if (i_cnt0) lsb <= q[1:0];
100+
if (i_en)
101+
data <= {i_init ? q : {W{i_sh_signed & data[31]}}, data[31:W]};
102+
if (i_en)
103+
data_tail <= data[B:1] & {B{~i_cnt_done}};
104+
end
105+
106+
wire [2*W+B-2:0] muxdata = {data[W+B-1:0],data_tail};
107+
wire [B:0] muxout = muxdata[{1'b0,shift_amount}+:W];
108+
86109
assign o_lsb = (MDU & i_mdu_op) ? 2'b00 : lsb;
87110
assign o_q = i_en ? muxout : {W{1'b0}};
88111
end

rtl/serv_bufreg2.v

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,19 +65,25 @@ module serv_bufreg2
6565
*/
6666

6767
wire [7:0] cnt_next;
68+
wire [7:0] sh_next;
6869
generate
6970
if (W == 1) begin : gen_cnt_w_eq_1
7071
assign cnt_next = {o_op_b, dhi[7], dhi[5:0]-6'd1};
72+
assign sh_next = {o_op_b, dhi[7:W]};
7173
end else if (W == 4) begin : gen_cnt_w_eq_4
7274
assign cnt_next = {o_op_b[3:2], dhi[5:0]-6'd4};
75+
assign sh_next = {o_op_b, dhi[7:W]};
76+
end else if (W == 8) begin : gen_cnt_w_eq_8
77+
assign cnt_next = {o_op_b[7:6], dhi[5:0]-6'd8};
78+
assign sh_next = o_op_b;
7379
end
7480
endgenerate
7581

7682
wire [7:0] dat_shamt = cnt_en ?
7783
//Down counter mode
7884
cnt_next :
7985
//Shift reg mode
80-
{o_op_b, dhi[7:W]};
86+
sh_next;
8187

8288
assign o_sh_done = dat_shamt[5];
8389

rtl/serv_csr.v

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ module serv_csr
7272
assign mstatus = ((mstatus_mie & i_cnt3) | (i_cnt11 | i_cnt12));
7373
end else if (W==4) begin : gen_mstatus_w4
7474
assign mstatus = {i_cnt11 | (mstatus_mie & i_cnt3), 2'b00, i_cnt12};
75+
end else if (W==8) begin : gen_mstatus_w8
76+
assign mstatus = {3'b000, i_cnt12, i_cnt11 | (mstatus_mie & i_cnt3), 3'b000};
7577
end
7678
endgenerate
7779

@@ -83,9 +85,28 @@ module serv_csr
8385

8486
wire timer_irq = i_mtip & mstatus_mie & mie_mtie;
8587

88+
generate
89+
if (W > 4) begin : gen_mcause_w_gt_4
90+
assign mcause = i_cnt0to3 ? {{W-4{1'b0}},mcause3_0} : //[3:0]
91+
i_cnt_done ? {mcause31,{B{1'b0}}} //[31]
92+
: {W{1'b0}};
93+
end else begin : gen_mcause_w_le_4
8694
assign mcause = i_cnt0to3 ? mcause3_0[B:0] : //[3:0]
8795
i_cnt_done ? {mcause31,{B{1'b0}}} //[31]
8896
: {W{1'b0}};
97+
end
98+
endgenerate
99+
100+
101+
wire [3:0] mcause3_0_next;
102+
103+
generate
104+
if (W == 1) begin : gen_mcause_next_w_eq_1
105+
assign mcause3_0_next = {csr_in, mcause3_0[3:1]};
106+
end else begin : gen_mcause_next_w_eq_4
107+
assign mcause3_0_next = csr_in[3:0];
108+
end
109+
endgenerate
89110

90111
assign o_csr_in = csr_in;
91112

@@ -109,7 +130,7 @@ module serv_csr
109130
These conditions are all mutually exclusive
110131
*/
111132
if ((i_trap & i_cnt_done) | i_mstatus_en & i_cnt3 & i_en | i_mret)
112-
mstatus_mie <= !i_trap & (i_mret ? mstatus_mpie : csr_in[B]);
133+
mstatus_mie <= !i_trap & (i_mret ? mstatus_mpie : csr_in[(W>4) ? 3 : B]);
113134

114135
/*
115136
Note: To save resources mstatus_mpie (mstatus bit 7) is not
@@ -141,10 +162,10 @@ module serv_csr
141162
ctrl => 0000 (jump=0)
142163
*/
143164
if (i_mcause_en & i_en & i_cnt0to3 | (i_trap & i_cnt_done)) begin
144-
mcause3_0[3] <= (i_e_op & !i_ebreak) | (!i_trap & csr_in[B]);
145-
mcause3_0[2] <= o_new_irq | i_mem_op | (!i_trap & ((W == 1) ? mcause3_0[3] : csr_in[(W == 1) ? 0 : 2]));
146-
mcause3_0[1] <= o_new_irq | i_e_op | (i_mem_op & i_mem_cmd) | (!i_trap & ((W == 1) ? mcause3_0[2] : csr_in[(W == 1) ? 0 : 1]));
147-
mcause3_0[0] <= o_new_irq | i_e_op | (!i_trap & ((W == 1) ? mcause3_0[1] : csr_in[0]));
165+
mcause3_0[3] <= (i_e_op & !i_ebreak) | (!i_trap & mcause3_0_next[3]);
166+
mcause3_0[2] <= o_new_irq | i_mem_op | (!i_trap & mcause3_0_next[2]);
167+
mcause3_0[1] <= o_new_irq | i_e_op | (!i_trap & mcause3_0_next[1]) | (i_mem_op & i_mem_cmd);
168+
mcause3_0[0] <= o_new_irq | i_e_op | (!i_trap & mcause3_0_next[0]);
148169
end
149170
if (i_mcause_en & i_cnt_done | i_trap)
150171
mcause31 <= i_trap ? o_new_irq : csr_in[B];

rtl/serv_ctrl.v

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ module serv_ctrl
5555
generate
5656
if (W == 1) begin : gen_plus_4_w_eq_1
5757
assign plus_4 = i_iscomp ? i_cnt1 : i_cnt2;
58-
end else if (W == 4) begin : gen_plus_4_w_eq_4
58+
end else if (W >= 4) begin : gen_plus_4_w_ge_4
5959
assign plus_4 = (i_cnt0 | i_cnt1) ? (i_iscomp ? 2 : 4) : 0;
6060
end
6161
endgenerate
@@ -70,6 +70,8 @@ module serv_ctrl
7070
assign new_pc = i_trap ? (i_csr_pc & !(i_cnt0 || i_cnt1)) : i_jump ? pc_plus_offset_aligned : pc_plus_4;
7171
end else if (W == 4) begin : gen_new_pc_w_eq_4
7272
assign new_pc = i_trap ? (i_csr_pc & ((i_cnt0 || i_cnt1) ? 4'b1100 : 4'b1111)) : i_jump ? pc_plus_offset_aligned : pc_plus_4;
73+
end else if (W == 8) begin : gen_new_pc_w_eq_8
74+
assign new_pc = i_trap ? (i_csr_pc & ((i_cnt0 || i_cnt1) ? 8'b11111100 : 8'b11111111)) : i_jump ? pc_plus_offset_aligned : pc_plus_4;
7375
end
7476
end else begin : gen_no_csr
7577
assign new_pc = i_jump ? pc_plus_offset_aligned : pc_plus_4;
@@ -78,7 +80,14 @@ module serv_ctrl
7880
assign o_rd = ({W{i_utype}} & pc_plus_offset_aligned) | (pc_plus_4 & {W{i_jal_or_jalr}});
7981

8082
assign offset_a = {W{i_pc_rel}} & pc;
81-
assign offset_b = i_utype ? (i_imm & {W{i_cnt12to15 | i_cnt16to31}}) : i_buf;
83+
generate
84+
if (W == 8) begin : gen_offset_w_eq_8
85+
assign offset_b = i_utype ? (i_imm & {{4{i_cnt12to15 | i_cnt16to31}}, {4{i_cnt16to31}}}) : i_buf;
86+
end else begin : gen_offset_w_lt_8
87+
assign offset_b = i_utype ? (i_imm & {W{i_cnt12to15 | i_cnt16to31}}) : i_buf;
88+
end
89+
endgenerate
90+
8291
assign {pc_plus_offset_cy,pc_plus_offset} = offset_a+offset_b+pc_plus_offset_cy_r_w;
8392

8493
generate

rtl/serv_immdec.v

Lines changed: 145 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ generate
9393
end
9494

9595
assign o_imm = i_cnt_done ? signbit : i_ctrl[0] ? imm11_7[0] : imm24_20[0];
96-
end else begin : gen_immdec_w_eq_4
96+
end else if (W == 4) begin : gen_immdec_w_eq_4
9797
reg [4:0] rd_addr;
9898
reg [4:0] rs1_addr;
9999
reg [4:0] rs2_addr;
@@ -223,6 +223,150 @@ generate
223223
assign o_imm[1] = i_ctrl[0] ? i8 : i21;
224224
assign o_imm[0] = i_ctrl[0] ? i7_2 : i20_2;
225225

226+
end else begin : gen_immdec_w_eq_8
227+
228+
reg [4:0] rd_addr;
229+
reg [4:0] rs1_addr;
230+
reg [4:0] rs2_addr;
231+
232+
reg i31;
233+
reg i30;
234+
reg i29;
235+
reg i28;
236+
reg i27;
237+
reg i26;
238+
reg i25;
239+
reg i24;
240+
reg i23;
241+
reg i22;
242+
reg i21;
243+
reg i20;
244+
reg i19;
245+
reg i18;
246+
reg i17;
247+
reg i16;
248+
reg i15;
249+
reg i14;
250+
reg i13;
251+
reg i12;
252+
reg i11;
253+
reg i10;
254+
reg i9;
255+
reg i8;
256+
reg i7;
257+
258+
reg i7_2;
259+
reg i20_2;
260+
261+
wire signbit = i31 & !i_csr_imm_en;
262+
263+
assign o_csr_imm[7] = 1'b0;
264+
assign o_csr_imm[6] = 1'b0;
265+
assign o_csr_imm[5] = 1'b0;
266+
assign o_csr_imm[4] = i19;
267+
assign o_csr_imm[3] = i18;
268+
assign o_csr_imm[2] = i17;
269+
assign o_csr_imm[1] = i16;
270+
assign o_csr_imm[0] = i15;
271+
272+
assign o_rd_addr = rd_addr;
273+
assign o_rs1_addr = rs1_addr;
274+
assign o_rs2_addr = rs2_addr;
275+
always @(posedge i_clk) begin
276+
if (i_wb_en) begin
277+
//Common
278+
i31 <= i_wb_rdt[31];
279+
280+
//Bit lane 3
281+
i19 <= i_wb_rdt[19];
282+
i15 <= i_wb_rdt[15];
283+
i20 <= i_wb_rdt[20];
284+
i7 <= i_wb_rdt[7];
285+
i27 <= i_wb_rdt[27];
286+
i23 <= i_wb_rdt[23];
287+
i10 <= i_wb_rdt[10];
288+
289+
//Bit lane 2
290+
i22 <= i_wb_rdt[22];
291+
i9 <= i_wb_rdt[ 9];
292+
i26 <= i_wb_rdt[26];
293+
i30 <= i_wb_rdt[30];
294+
i14 <= i_wb_rdt[14];
295+
i18 <= i_wb_rdt[18];
296+
297+
//Bit lane 1
298+
i21 <= i_wb_rdt[21];
299+
i8 <= i_wb_rdt[ 8];
300+
i25 <= i_wb_rdt[25];
301+
i29 <= i_wb_rdt[29];
302+
i13 <= i_wb_rdt[13];
303+
i17 <= i_wb_rdt[17];
304+
305+
//Bit lane 0
306+
i11 <= i_wb_rdt[11];
307+
i7_2 <= i_wb_rdt[7 ];
308+
i20_2 <= i_wb_rdt[20];
309+
i24 <= i_wb_rdt[24];
310+
i28 <= i_wb_rdt[28];
311+
i12 <= i_wb_rdt[12];
312+
i16 <= i_wb_rdt[16];
313+
314+
rd_addr <= i_wb_rdt[11:7];
315+
rs1_addr <= i_wb_rdt[19:15];
316+
rs2_addr <= i_wb_rdt[24:20];
317+
end
318+
if (i_cnt_en) begin
319+
//Bit lane 6, 7
320+
i10 <= i_ctrl[2] ? i7 : i_ctrl[1] ? signbit : i20;
321+
i23 <= i_ctrl[2] ? i7 : i_ctrl[1] ? signbit : i20;
322+
i27 <= i_ctrl[2] ? signbit : i_ctrl[1] ? signbit : i15;
323+
i7 <= signbit;
324+
i20 <= i19;
325+
i15 <= i_ctrl[3] ? signbit : i23;
326+
i19 <= i_ctrl[3] ? signbit : i27;
327+
328+
329+
//Bit lane 4, 5
330+
i22 <= i30;
331+
i9 <= i30;
332+
i26 <= (i_ctrl[1] | i_ctrl[2]) ? signbit : i14;
333+
i30 <= (i_ctrl[1] | i_ctrl[2]) ? signbit : i18;
334+
i14 <= i_ctrl[3] ? signbit : i22;
335+
i18 <= i_ctrl[3] ? signbit : i26;
336+
337+
338+
//Bit lane 2, 3
339+
i21 <= i29;
340+
i8 <= i29;
341+
i25 <= (i_ctrl[1] | i_ctrl[2]) ? signbit : i13;
342+
i29 <= (i_ctrl[1] | i_ctrl[2]) ? signbit : i17;
343+
i13 <= i_ctrl[3] ? signbit : i21;
344+
i17 <= i_ctrl[3] ? signbit : i25;
345+
346+
347+
//Bit lane 0, 1
348+
i7_2 <= i28;
349+
i20_2 <= i28;
350+
i28 <= (i_ctrl[1] | i_ctrl[2]) ? signbit : i16;
351+
i16 <= i_ctrl[3] ? signbit : i24;
352+
i11 <= (i_ctrl[1] | i_ctrl[2]) ? signbit : i12;
353+
i24 <= (i_ctrl[1] | i_ctrl[2]) ? signbit : i12;
354+
i12 <= i_ctrl[3] ? signbit : i20_2;
355+
end
356+
end
357+
358+
assign o_imm[7] = (i_cnt_done ? signbit : (i_ctrl[0] ? i27 : i27));
359+
assign o_imm[3] = ((i_ctrl[0] ? i10 : i23));
360+
361+
assign o_imm[6] = i_ctrl[0] ? i26 : i26;
362+
assign o_imm[2] = i_ctrl[0] ? i9 : i22;
363+
364+
assign o_imm[5] = i_ctrl[0] ? i25 : i25;
365+
assign o_imm[1] = i_ctrl[0] ? i8 : i21;
366+
367+
assign o_imm[4] = i_ctrl[0] ? i11 : i24;
368+
assign o_imm[0] = i_ctrl[0] ? i7_2 : i20_2;
369+
226370
end
227371
endgenerate
228372

rtl/serv_rf_ram_if.v

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,13 @@ module serv_rf_ram_if
9191

9292
assign o_wen = (wtrig0 & wen0_r) | (wtrig1 & wen1_r);
9393

94-
assign wcnt = rcnt-4;
94+
generate
95+
if (W > 4) begin : gen_wcnt_w_gt_4
96+
assign wcnt = rcnt;
97+
end else begin : gen_wcnt_w_le_4
98+
assign wcnt = rcnt-4;
99+
end
100+
endgenerate
95101

96102
always @(posedge i_clk) begin
97103
if (wcnt[0]) begin

rtl/serv_state.v

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,15 +73,26 @@ module serv_state
7373
assign o_mem_bytecnt = o_cnt[4:3];
7474

7575
assign o_cnt0to3 = (o_cnt[4:2] == 3'd0);
76-
assign o_cnt12to15 = (!o_cnt[4] & (o_cnt[3:2] == 2'b11));
7776
assign o_cnt16to31 = o_cnt[4];
7877
assign o_cnt0 = (o_cnt[4:2] == 3'd0) & cnt_r[0];
7978
assign o_cnt1 = (o_cnt[4:2] == 3'd0) & cnt_r[1];
8079
assign o_cnt2 = (o_cnt[4:2] == 3'd0) & cnt_r[2];
8180
assign o_cnt3 = (o_cnt[4:2] == 3'd0) & cnt_r[3];
82-
assign o_cnt7 = (o_cnt[4:2] == 3'd1) & cnt_r[3];
8381
assign o_cnt11 = (o_cnt[4:2] == 3'd2) & cnt_r[3];
84-
assign o_cnt12 = (o_cnt[4:2] == 3'd3) & cnt_r[0];
82+
83+
generate
84+
if (W == 8) begin : gen_cnt_w_8
85+
assign o_cnt12to15 = (o_cnt[4:3] == 2'b01);
86+
assign o_cnt7 = o_cnt0 & o_cnt_en;
87+
assign o_cnt12 = o_cnt11;
88+
assign o_cnt_done = (o_cnt[4:3] == 2'b11) & cnt_r[3];
89+
end else begin : gen_cnt_w_lt_8
90+
assign o_cnt12to15 = (o_cnt[4:2] == 3'b011);
91+
assign o_cnt7 = (o_cnt[4:2] == 3'd1) & cnt_r[3];
92+
assign o_cnt12 = (o_cnt[4:2] == 3'd3) & cnt_r[0];
93+
assign o_cnt_done = (o_cnt[4:2] == 3'b111) & cnt_r[3];
94+
end
95+
endgenerate
8596

8697
//Take branch for jump or branch instructions (opcode == 1x0xx) if
8798
//a) It's an unconditional branch (opcode[0] == 1)
@@ -133,8 +144,6 @@ module serv_state
133144

134145
assign o_init = i_two_stage_op & !i_new_irq & !init_done;
135146

136-
assign o_cnt_done = (o_cnt[4:2] == 3'b111) & cnt_r[3];
137-
138147
always @(posedge i_clk) begin
139148
//ibus_cyc changes on three conditions.
140149
//1. i_rst is asserted. Together with the async gating above, o_ibus_cyc
@@ -209,6 +218,19 @@ module serv_state
209218
end
210219
assign cnt_r = 4'b1111;
211220
assign o_cnt_en = cnt_en;
221+
end else if (W == 8) begin : gen_cnt_w_eq_8
222+
reg cnt_en;
223+
always @(posedge i_clk) begin
224+
if (i_rf_ready) cnt_en <= 1; else
225+
if (o_cnt_done) cnt_en <= 0;
226+
o_cnt <= o_cnt + { 1'd0, cnt_en, 1'b0};
227+
if (i_rst & (RESET_STRATEGY != "NONE")) begin
228+
o_cnt <= 3'd0;
229+
cnt_en <= 1'b0;
230+
end
231+
end
232+
assign cnt_r = 4'b1111;
233+
assign o_cnt_en = cnt_en;
212234
end
213235
endgenerate
214236

0 commit comments

Comments
 (0)