From cbbdaed112121c8e28650ce03595c90d554584fb Mon Sep 17 00:00:00 2001 From: Olof Kindgren Date: Fri, 2 Nov 2018 13:48:08 +0100 Subject: [PATCH] slli, srli, add, sll, sltiu, slt, xor, srl, sra, or, and --- rtl/ser_shift.v | 14 ++++--- rtl/serv_alu.v | 28 +++++++++++--- rtl/serv_decode.v | 91 ++++++++++++++++++++++++++-------------------- rtl/serv_params.vh | 11 ++++-- rtl/serv_top.v | 8 +++- 5 files changed, 96 insertions(+), 56 deletions(-) diff --git a/rtl/ser_shift.v b/rtl/ser_shift.v index 2ec11b5..0464dd0 100644 --- a/rtl/ser_shift.v +++ b/rtl/ser_shift.v @@ -4,7 +4,8 @@ module ser_shift input i_clk, input i_load, input [4:0] i_shamt, - input i_sr, + input i_signed, + input i_right, input i_d, output o_q); @@ -23,19 +24,20 @@ module ser_shift always @(posedge i_clk) begin cnt <= cnt + 1; + if (cnt == 31) begin + signbit <= shiftreg[cnt]; + wrapped <= 1'b1; + end if (i_load) begin cnt <= i_shamt; wrapped <= 1'b0; end - if (cnt == 31) begin - signbit <= shiftreg[cnt]; - wrapped <= 1'b1; - end end - assign o_q = wrapped ? signbit : shiftreg[cnt]; + wire shiftreg_valid = (i_shamt == 0) | (wrapped^i_right); + assign o_q = shiftreg_valid ? shiftreg[cnt] : signbit & i_signed; endmodule diff --git a/rtl/serv_alu.v b/rtl/serv_alu.v index 74a33f7..1695b7c 100644 --- a/rtl/serv_alu.v +++ b/rtl/serv_alu.v @@ -12,7 +12,9 @@ module serv_alu input i_cmp_uns, output o_cmp, input i_shamt_en, - input [1:0] i_rd_sel, + input i_sh_right, + input i_sh_signed, + input [2:0] i_rd_sel, output o_rd); `include "serv_params.vh" @@ -28,12 +30,24 @@ module serv_alu wire v; reg msb_lt = 1'b0; reg init_r; + wire shamt_l; + wire shamt_ser; - + ser_add ser_add_inv_shamt_plus1 + ( + .clk (clk), + .a (~i_op_b), + .b (plus_1), + .clr (!i_en), + .q (shamt_l), + .o_v ()); + + assign shamt_ser = i_sh_right ? i_op_b : shamt_l; + shift_reg #(.LEN (5)) shamt_reg (.clk (clk), .i_en (i_shamt_en), - .i_d (i_op_b), + .i_d (shamt_ser), .o_q (shamt[0]), .o_par (shamt[4:1])); @@ -42,7 +56,8 @@ module serv_alu .i_clk (clk), .i_load (i_init), .i_shamt (shamt), - .i_sr (/*FIXME*/), + .i_signed (i_sh_signed), + .i_right (i_sh_right), .i_d (i_rs1), .o_q (result_sh)); @@ -93,7 +108,10 @@ module serv_alu assign o_rd = (i_rd_sel == ALU_RESULT_ADD) ? result_add : (i_rd_sel == ALU_RESULT_SR) ? result_sh : - (i_rd_sel == ALU_RESULT_LT) ? (result_lt2 & init_r & ~i_init): + (i_rd_sel == ALU_RESULT_LT) ? (result_lt2 & init_r & ~i_init) : + (i_rd_sel == ALU_RESULT_XOR) ? i_rs1^i_op_b : + (i_rd_sel == ALU_RESULT_OR) ? i_rs1|i_op_b : + (i_rd_sel == ALU_RESULT_AND) ? i_rs1&i_op_b : 1'bx; always @(posedge clk) begin diff --git a/rtl/serv_decode.v b/rtl/serv_decode.v index ad01748..b865415 100644 --- a/rtl/serv_decode.v +++ b/rtl/serv_decode.v @@ -1,37 +1,39 @@ module serv_decode ( - input clk, - input [31:0] i_i_rd_dat, - input i_i_rd_vld, - output reg o_i_rd_rdy = 1'b1, - output o_ctrl_en, - output o_ctrl_jump, - output o_ctrl_jalr, - output o_ctrl_auipc, - output o_rf_rd_en, - output [4:0] o_rf_rd_addr, - output o_rf_rs_en, - output [4:0] o_rf_rs1_addr, - output [4:0] o_rf_rs2_addr, - output o_alu_en, - output o_alu_init, - output o_alu_sub, - output reg o_alu_cmp_sel, - output o_alu_cmp_neg, - output reg o_alu_cmp_uns, - input i_alu_cmp, - output o_alu_shamt_en, - output [1:0] o_alu_rd_sel, - output o_mem_en, - output o_mem_cmd, - output o_mem_init, - output reg o_mem_dat_valid, - input i_mem_busy, - output [2:0] o_funct3, - output reg o_imm, - output o_offset_source, - output o_op_b_source, - output [1:0] o_rd_source); + input clk, + input [31:0] i_i_rd_dat, + input i_i_rd_vld, + output reg o_i_rd_rdy = 1'b1, + output o_ctrl_en, + output o_ctrl_jump, + output o_ctrl_jalr, + output o_ctrl_auipc, + output o_rf_rd_en, + output [4:0] o_rf_rd_addr, + output o_rf_rs_en, + output [4:0] o_rf_rs1_addr, + output [4:0] o_rf_rs2_addr, + output o_alu_en, + output o_alu_init, + output o_alu_sub, + output reg o_alu_cmp_sel, + output o_alu_cmp_neg, + output reg o_alu_cmp_uns, + input i_alu_cmp, + output o_alu_shamt_en, + output o_alu_sh_signed, + output o_alu_sh_right, + output reg [2:0] o_alu_rd_sel, + output o_mem_en, + output o_mem_cmd, + output o_mem_init, + output reg o_mem_dat_valid, + input i_mem_busy, + output [2:0] o_funct3, + output reg o_imm, + output o_offset_source, + output o_op_b_source, + output [1:0] o_rd_source); `include "serv_params.vh" @@ -63,7 +65,8 @@ module serv_decode wire shift_op; assign mem_op = (opcode == OP_LOAD) | (opcode == OP_STORE); - assign shift_op = (opcode == OP_OPIMM) & (o_funct3[1:0] == 2'b01); + assign shift_op = ((opcode == OP_OPIMM) & (o_funct3[1:0] == 2'b01)) | + ((opcode == OP_OP ) & (o_funct3[1:0] == 2'b01)); assign o_ctrl_en = running; assign o_ctrl_jump = (opcode == OP_JAL) | @@ -88,7 +91,7 @@ module serv_decode assign o_alu_init = (state == COMPARE) | (state == SH_INIT); - assign o_alu_sub = ((opcode == OP_OP) & i_i_rd_dat[30]) ? 1'b1 : + assign o_alu_sub = (opcode == OP_OP) ? i_i_rd_dat[30] /* ? 1'b1*/ : ((opcode == OP_BRANCH) & (o_funct3 == 3'b100)) ? 1'b1 : ((opcode == OP_BRANCH) & (o_funct3 == 3'b101)) ? 1'b1 : ((opcode == OP_BRANCH) & (o_funct3 == 3'b110)) ? 1'b1 : @@ -113,13 +116,21 @@ module serv_decode 3'b11? : o_alu_cmp_uns = 1'b1; default : o_alu_cmp_uns = 1'bx; endcase + + casez(o_funct3) + 3'b000 : o_alu_rd_sel = ALU_RESULT_ADD; + 3'b001 : o_alu_rd_sel = ALU_RESULT_SR; + 3'b01? : o_alu_rd_sel = ALU_RESULT_LT; + 3'b100 : o_alu_rd_sel = ALU_RESULT_XOR; + 3'b101 : o_alu_rd_sel = ALU_RESULT_SR; + 3'b110 : o_alu_rd_sel = ALU_RESULT_OR; + 3'b111 : o_alu_rd_sel = ALU_RESULT_AND; + default : o_alu_rd_sel = 3'bxx; + endcase end assign o_alu_shamt_en = (state == SH_INIT) & (cnt < 5); - - assign o_alu_rd_sel = (o_funct3 == 3'b000) ? ALU_RESULT_ADD : - (o_funct3[2:1] == 2'b01) ? ALU_RESULT_LT : - (o_funct3 == 3'b101) ? ALU_RESULT_SR : -2'bxx; + assign o_alu_sh_signed = i_i_rd_dat[30]; + assign o_alu_sh_right = o_funct3[2]; assign o_mem_en = mem_op & cnt_en; assign o_mem_cmd = (opcode == OP_STORE); @@ -209,7 +220,7 @@ module serv_decode IDLE : begin if (go) state <= (opcode == OP_BRANCH) ? COMPARE : - ((opcode == OP_OPIMM) & (o_funct3[2:1] == 2'b01)) ? COMPARE : + (((opcode == OP_OPIMM) | (opcode == OP_OP))& (o_funct3[2:1] == 2'b01)) ? COMPARE : mem_op ? MEM_INIT : shift_op ? SH_INIT : RUN; end diff --git a/rtl/serv_params.vh b/rtl/serv_params.vh index a42bf65..80a9c34 100644 --- a/rtl/serv_params.vh +++ b/rtl/serv_params.vh @@ -12,10 +12,13 @@ localparam [0:0] OP_B_SOURCE_IMM = 1'd0, OP_B_SOURCE_RS2 = 1'd1; -localparam[1:0] - ALU_RESULT_ADD = 2'd0, - ALU_RESULT_SR = 2'd1, - ALU_RESULT_LT = 2'd2; +localparam[2:0] + ALU_RESULT_ADD = 3'd0, + ALU_RESULT_SR = 3'd1, + ALU_RESULT_LT = 3'd2, + ALU_RESULT_XOR = 3'd3, + ALU_RESULT_OR = 3'd4, + ALU_RESULT_AND = 3'd5; localparam [0:0] ALU_CMP_LT = 1'b0, diff --git a/rtl/serv_top.v b/rtl/serv_top.v index 6794335..4fa2ad6 100644 --- a/rtl/serv_top.v +++ b/rtl/serv_top.v @@ -79,7 +79,9 @@ module serv_top wire alu_cmp_uns; wire alu_cmp; wire alu_shamt_en; - wire [1:0] alu_rd_sel; + wire alu_sh_signed; + wire alu_sh_right; + wire [2:0] alu_rd_sel; wire rs1; wire rs2; @@ -118,6 +120,8 @@ module serv_top .o_alu_cmp_uns (alu_cmp_uns), .i_alu_cmp (alu_cmp), .o_alu_shamt_en (alu_shamt_en), + .o_alu_sh_signed (alu_sh_signed), + .o_alu_sh_right (alu_sh_right), .o_alu_rd_sel (alu_rd_sel), .o_rf_rd_en (rd_en), .o_rf_rd_addr (rd_addr), @@ -176,6 +180,8 @@ module serv_top .i_cmp_uns (alu_cmp_uns), .o_cmp (alu_cmp), .i_shamt_en (alu_shamt_en), + .i_sh_right (alu_sh_right), + .i_sh_signed (alu_sh_signed), .i_rd_sel (alu_rd_sel), .o_rd (alu_rd));