1
0
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:
Olof Kindgren 2019-01-22 09:47:11 +01:00
parent 102936ba40
commit a550137453
6 changed files with 73 additions and 41 deletions

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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