mirror of
https://github.com/olofk/serv.git
synced 2026-01-13 15:17:25 +00:00
Use bufreg for shifter
This commit is contained in:
parent
102936ba40
commit
a550137453
@ -5,40 +5,27 @@ module ser_shift
|
||||
input wire i_rst,
|
||||
input wire i_load,
|
||||
input wire [4:0] i_shamt,
|
||||
input wire i_signed,
|
||||
input wire i_shamt_msb,
|
||||
input wire i_signbit,
|
||||
input wire i_right,
|
||||
output wire o_done,
|
||||
input wire i_d,
|
||||
output wire o_q);
|
||||
|
||||
wire [31:0] shiftreg;
|
||||
|
||||
reg signbit = 1'b0;
|
||||
reg wrapped = 1'b0;
|
||||
reg [4:0] cnt = 5'd0;
|
||||
|
||||
shift_reg #(.LEN (32)) sh_reg
|
||||
(.clk (i_clk),
|
||||
.i_rst (i_rst),
|
||||
.i_en (i_load),
|
||||
.i_d (i_d),
|
||||
.o_q (shiftreg[0]),
|
||||
.o_par (shiftreg[31:1]));
|
||||
|
||||
reg signbit;
|
||||
reg [5:0] cnt;
|
||||
reg wrapped;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
cnt <= cnt + 5'd1;
|
||||
if (cnt == 31) begin
|
||||
signbit <= shiftreg[cnt];
|
||||
wrapped <= 1'b1;
|
||||
end
|
||||
cnt <= cnt + 6'd1;
|
||||
if (i_load) begin
|
||||
cnt <= i_shamt;
|
||||
wrapped <= 1'b0;
|
||||
cnt <= 6'd0;
|
||||
signbit <= i_signbit & i_right;
|
||||
end
|
||||
|
||||
|
||||
wrapped <= cnt[5] | (i_shamt_msb & !i_right);
|
||||
end
|
||||
|
||||
wire shiftreg_valid = (i_shamt == 0) | (wrapped^i_right);
|
||||
assign o_q = shiftreg_valid ? shiftreg[cnt] : signbit & i_signed;
|
||||
assign o_done = (cnt == i_shamt);
|
||||
assign o_q = (i_right^wrapped) ? i_d : signbit;
|
||||
|
||||
endmodule
|
||||
|
||||
@ -6,6 +6,7 @@ module serv_alu
|
||||
input wire i_en,
|
||||
input wire i_rs1,
|
||||
input wire i_op_b,
|
||||
input wire i_buf,
|
||||
input wire i_init,
|
||||
input wire i_cnt_done,
|
||||
input wire i_sub,
|
||||
@ -17,6 +18,7 @@ module serv_alu
|
||||
input wire i_shamt_en,
|
||||
input wire i_sh_right,
|
||||
input wire i_sh_signed,
|
||||
output wire o_sh_done,
|
||||
input wire [1:0] i_rd_sel,
|
||||
output wire o_rd);
|
||||
|
||||
@ -30,6 +32,7 @@ module serv_alu
|
||||
reg result_lt_r;
|
||||
|
||||
wire [4:0] shamt;
|
||||
reg shamt_msb;
|
||||
|
||||
reg en_r;
|
||||
wire v;
|
||||
@ -54,11 +57,18 @@ module serv_alu
|
||||
.i_rst (i_rst),
|
||||
.i_load (i_init),
|
||||
.i_shamt (shamt),
|
||||
.i_signed (i_sh_signed),
|
||||
.i_shamt_msb (shamt_msb),
|
||||
.i_signbit (i_sh_signed & i_rs1),
|
||||
.i_right (i_sh_right),
|
||||
.i_d (i_rs1),
|
||||
.o_done (o_sh_done),
|
||||
.i_d (i_buf),
|
||||
.o_q (result_sh));
|
||||
|
||||
wire b_inv_plus_1_cy;
|
||||
|
||||
always @(posedge clk)
|
||||
if (i_shamt_en)
|
||||
shamt_msb <= b_inv_plus_1_cy;
|
||||
|
||||
ser_add ser_add_inv_plus_1
|
||||
(
|
||||
@ -68,7 +78,7 @@ module serv_alu
|
||||
.b (plus_1),
|
||||
.clr (!i_en),
|
||||
.q (b_inv_plus_1),
|
||||
.o_v ());
|
||||
.o_v (b_inv_plus_1_cy));
|
||||
|
||||
wire add_b = i_sub ? b_inv_plus_1 : i_op_b;
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@ module serv_bufreg
|
||||
input wire [3:0] i_cnt_r,
|
||||
input wire i_en,
|
||||
input wire i_clr,
|
||||
input wire i_loop,
|
||||
input wire i_rs1,
|
||||
input wire i_rs1_en,
|
||||
input wire i_imm,
|
||||
@ -26,7 +27,7 @@ module serv_bufreg
|
||||
if (i_rst)
|
||||
data <= 32'd0;
|
||||
else if (i_en)
|
||||
data <= {q, data[31:1]};
|
||||
data <= {i_loop ? o_q : q, data[31:1]};
|
||||
|
||||
if ((i_cnt[4:2] == 3'd0) & i_cnt_r[0] & i_en)
|
||||
o_lsb[0] <= q;
|
||||
|
||||
@ -11,6 +11,9 @@ module serv_decode
|
||||
output wire [4:0] o_cnt,
|
||||
output reg [3:0] o_cnt_r,
|
||||
output wire o_cnt_done,
|
||||
output reg o_bufreg_hold,
|
||||
output wire o_bufreg_imm_en,
|
||||
output wire o_bufreg_loop,
|
||||
output wire o_ctrl_en,
|
||||
output wire o_ctrl_pc_en,
|
||||
output reg o_ctrl_jump,
|
||||
@ -21,6 +24,7 @@ module serv_decode
|
||||
output wire o_ctrl_trap,
|
||||
output wire o_ctrl_mret,
|
||||
input wire i_ctrl_misalign,
|
||||
output wire o_rf_rs_en,
|
||||
output wire o_rf_rd_en,
|
||||
output reg [4:0] o_rf_rd_addr,
|
||||
output reg [4:0] o_rf_rs1_addr,
|
||||
@ -36,6 +40,7 @@ module serv_decode
|
||||
output wire o_alu_shamt_en,
|
||||
output wire o_alu_sh_signed,
|
||||
output wire o_alu_sh_right,
|
||||
input wire i_alu_sh_done,
|
||||
output reg [1:0] o_alu_rd_sel,
|
||||
output wire o_mem_en,
|
||||
output wire o_mem_cmd,
|
||||
@ -104,6 +109,9 @@ module serv_decode
|
||||
|
||||
assign e_op = (opcode[4:2] == 3'b111) & !op21 & !(|o_funct3);
|
||||
|
||||
assign o_bufreg_imm_en = !opcode[2];
|
||||
assign o_bufreg_loop = op_or_opimm & !(state == INIT);
|
||||
|
||||
assign o_ctrl_pc_en = running | o_ctrl_trap;
|
||||
wire take_branch = (opcode[4:2] == 3'b110) & (opcode[0] | i_alu_cmp);
|
||||
|
||||
@ -273,6 +281,8 @@ module serv_decode
|
||||
o_csr_mcause <= {!op20,3'b011};
|
||||
end
|
||||
|
||||
assign o_rf_rs_en = two_stage_op ? (state == INIT) : o_ctrl_pc_en;
|
||||
|
||||
//slt*, branch/jump, shift, load/store
|
||||
wire two_stage_op =
|
||||
slt_op | (opcode[4:2] == 3'b110) | (opcode[2:1] == 2'b00) |
|
||||
@ -295,6 +305,8 @@ module serv_decode
|
||||
|
||||
cnt_done <= (cnt[4:2] == 3'b111) & o_cnt_r[2];
|
||||
|
||||
o_bufreg_hold <= 1'b0;
|
||||
|
||||
case (state)
|
||||
IDLE : begin
|
||||
if (i_rf_ready) begin
|
||||
@ -303,14 +315,21 @@ module serv_decode
|
||||
state <= INIT;
|
||||
if (e_op | pending_irq)
|
||||
state <= TRAP;
|
||||
end
|
||||
end else if (i_alu_sh_done & shift_op & stage_one_done)
|
||||
state <= RUN;
|
||||
end
|
||||
INIT : begin
|
||||
stage_one_done <= 1'b1;
|
||||
|
||||
if (cnt_done)
|
||||
state <= (i_mem_misalign | (take_branch & i_ctrl_misalign)) ? TRAP :
|
||||
mem_op ? IDLE : RUN;
|
||||
if (i_mem_misalign | (take_branch & i_ctrl_misalign))
|
||||
state <= TRAP;
|
||||
else if (mem_op | shift_op ) begin
|
||||
state <= IDLE;
|
||||
o_bufreg_hold <= 1'b1;
|
||||
end
|
||||
else
|
||||
state <= RUN;
|
||||
end
|
||||
RUN : begin
|
||||
stage_one_done <= 1'b0;
|
||||
|
||||
@ -60,7 +60,7 @@ module serv_mem_if
|
||||
assign o_wb_sel[0] = (bytepos == 2'b00);
|
||||
|
||||
assign o_wb_we = i_cmd;
|
||||
wire [1:0] bytepos;
|
||||
reg [1:0] bytepos;
|
||||
|
||||
|
||||
wire wbyte0 = (i_bytecnt == 2'b00);
|
||||
@ -77,9 +77,10 @@ module serv_mem_if
|
||||
|
||||
wire [1:0] dat_sel = i_bytecnt[1] ? i_bytecnt : (i_bytecnt | bytepos);
|
||||
|
||||
assign bytepos = i_lsb;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_init)
|
||||
bytepos <= i_lsb;
|
||||
|
||||
if (dat0_en)
|
||||
dat0 <= {i_rs2, dat0[7:1]};
|
||||
if (dat1_en)
|
||||
|
||||
@ -76,6 +76,10 @@ module serv_top
|
||||
wire cnt_done;
|
||||
wire [2:0] funct3;
|
||||
|
||||
wire bufreg_hold;
|
||||
wire bufreg_imm_en;
|
||||
wire bufreg_loop;
|
||||
|
||||
wire alu_en;
|
||||
wire alu_init;
|
||||
wire alu_sub;
|
||||
@ -87,11 +91,13 @@ module serv_top
|
||||
wire alu_shamt_en;
|
||||
wire alu_sh_signed;
|
||||
wire alu_sh_right;
|
||||
wire alu_sh_done;
|
||||
wire [1:0] alu_rd_sel;
|
||||
|
||||
wire rf_ready;
|
||||
wire rs1;
|
||||
wire rs2;
|
||||
wire rs_en;
|
||||
wire rd_en;
|
||||
|
||||
wire op_b_source;
|
||||
@ -136,10 +142,13 @@ module serv_top
|
||||
.i_timer_irq_en (timer_irq_en),
|
||||
.i_wb_rdt (i_ibus_rdt),
|
||||
.i_wb_en (o_ibus_cyc & i_ibus_ack),
|
||||
.i_rf_ready (rf_ready),
|
||||
.i_rf_ready (rf_ready | i_dbus_ack),
|
||||
.o_cnt (cnt),
|
||||
.o_cnt_r (cnt_r),
|
||||
.o_cnt_done (cnt_done),
|
||||
.o_bufreg_hold (bufreg_hold),
|
||||
.o_bufreg_imm_en (bufreg_imm_en),
|
||||
.o_bufreg_loop (bufreg_loop),
|
||||
.o_ctrl_en (ctrl_en),
|
||||
.o_ctrl_pc_en (ctrl_pc_en),
|
||||
.o_ctrl_jump (jump),
|
||||
@ -162,7 +171,9 @@ module serv_top
|
||||
.o_alu_shamt_en (alu_shamt_en),
|
||||
.o_alu_sh_signed (alu_sh_signed),
|
||||
.o_alu_sh_right (alu_sh_right),
|
||||
.i_alu_sh_done (alu_sh_done),
|
||||
.o_alu_rd_sel (alu_rd_sel),
|
||||
.o_rf_rs_en (rs_en),
|
||||
.o_rf_rd_en (rd_en),
|
||||
.o_rf_rd_addr (rd_addr),
|
||||
.o_rf_rs1_addr (rs1_addr),
|
||||
@ -199,12 +210,13 @@ module serv_top
|
||||
.i_rst (i_rst),
|
||||
.i_cnt (cnt),
|
||||
.i_cnt_r (cnt_r),
|
||||
.i_en (alu_en),
|
||||
.i_en (!(bufreg_hold | o_dbus_cyc)),
|
||||
.i_clr (!mem_en),
|
||||
.i_loop (bufreg_loop),
|
||||
.i_rs1 (rs1),
|
||||
.i_rs1_en (1'b1),
|
||||
.i_imm (imm),
|
||||
.i_imm_en (1'b1),
|
||||
.i_imm_en (bufreg_imm_en),
|
||||
.o_lsb (lsb),
|
||||
.o_reg (bufreg_out),
|
||||
.o_q (bad_adr));
|
||||
@ -250,6 +262,7 @@ module serv_top
|
||||
.i_en (alu_en),
|
||||
.i_rs1 (rs1),
|
||||
.i_op_b (op_b),
|
||||
.i_buf (bad_adr), //FIXME
|
||||
.i_init (alu_init),
|
||||
.i_cnt_done (cnt_done),
|
||||
.i_sub (alu_sub),
|
||||
@ -261,6 +274,7 @@ module serv_top
|
||||
.i_shamt_en (alu_shamt_en),
|
||||
.i_sh_right (alu_sh_right),
|
||||
.i_sh_signed (alu_sh_signed),
|
||||
.o_sh_done (alu_sh_done),
|
||||
.i_rd_sel (alu_rd_sel),
|
||||
.o_rd (alu_rd));
|
||||
|
||||
@ -268,7 +282,7 @@ module serv_top
|
||||
(
|
||||
.i_clk (clk),
|
||||
.i_rst (i_rst),
|
||||
.i_go (i_ibus_ack | i_dbus_ack),
|
||||
.i_go (i_ibus_ack),
|
||||
.o_ready (rf_ready),
|
||||
.i_rd_en (rd_en),
|
||||
.i_rd_addr (rd_addr),
|
||||
@ -345,7 +359,7 @@ module serv_top
|
||||
rvfi_insn <= i_ibus_rdt;
|
||||
|
||||
ctrl_pc_en_r <= ctrl_pc_en;
|
||||
if (alu_en) begin
|
||||
if (rs_en) begin
|
||||
rs1_fv <= {rs1,rs1_fv[31:1]};
|
||||
rs2_fv <= {rs2,rs2_fv[31:1]};
|
||||
end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user