mirror of
https://github.com/olofk/serv.git
synced 2026-02-10 17:49:45 +00:00
jalr, blt
This commit is contained in:
@@ -4,12 +4,15 @@ module ser_add
|
||||
input a,
|
||||
input b,
|
||||
input clr,
|
||||
output q);
|
||||
output q,
|
||||
output o_v);
|
||||
|
||||
reg c = 1'b0;
|
||||
assign o_v = (a&b | a&c_r | b&c_r);
|
||||
|
||||
assign q = a ^ b ^ c;
|
||||
reg c_r = 1'b0;
|
||||
|
||||
assign q = a ^ b ^ c_r;
|
||||
always @(posedge clk)
|
||||
c <= !clr & (a&b | a&c | b&c);
|
||||
c_r <= !clr & o_v;
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -3,29 +3,29 @@ module serv_alu
|
||||
(
|
||||
input clk,
|
||||
input i_en,
|
||||
input [2:0] i_op,
|
||||
input [2:0] i_funct3,
|
||||
input i_rs1,
|
||||
input i_op_b,
|
||||
input i_init,
|
||||
input i_init,
|
||||
input i_sub,
|
||||
input i_cmp_sel,
|
||||
input i_cmp_neg,
|
||||
output o_cmp,
|
||||
input i_shamt_en,
|
||||
input [1:0] i_rd_sel,
|
||||
output o_rd);
|
||||
|
||||
`include "serv_params.vh"
|
||||
|
||||
localparam[2:0]
|
||||
BEQ = 3'b000,
|
||||
BNE = 3'b001;
|
||||
wire result_add;
|
||||
wire result_eq;
|
||||
reg result_lt = 1'b0;
|
||||
wire result_sh;
|
||||
|
||||
wire result_add;
|
||||
wire result_eq;
|
||||
wire result_sh;
|
||||
wire [4:0] shamt;
|
||||
|
||||
wire [4:0] shamt;
|
||||
reg en_r;
|
||||
wire v;
|
||||
|
||||
reg en_r;
|
||||
|
||||
shift_reg #(.LEN (5)) shamt_reg
|
||||
(.clk (clk),
|
||||
.i_en (i_shamt_en),
|
||||
@@ -51,10 +51,10 @@ module serv_alu
|
||||
.a (~i_op_b),
|
||||
.b (plus_1),
|
||||
.clr (!i_en),
|
||||
.q (b_inv_plus_1));
|
||||
.q (b_inv_plus_1),
|
||||
.o_v ());
|
||||
|
||||
wire add_b = sub ? b_inv_plus_1 : i_op_b;
|
||||
wire sub = i_op[1];
|
||||
wire add_b = i_sub ? b_inv_plus_1 : i_op_b;
|
||||
|
||||
ser_add ser_add
|
||||
(
|
||||
@@ -62,7 +62,8 @@ module serv_alu
|
||||
.a (i_rs1),
|
||||
.b (add_b),
|
||||
.clr (!i_en),
|
||||
.q (result_add));
|
||||
.q (result_add),
|
||||
.o_v (v));
|
||||
|
||||
ser_eq ser_eq
|
||||
(
|
||||
@@ -72,16 +73,17 @@ module serv_alu
|
||||
.clr (!i_init),
|
||||
.o_q (result_eq));
|
||||
|
||||
assign o_cmp = (i_funct3 == BEQ) ? result_eq :
|
||||
(i_funct3 == BNE) ? ~result_eq : 1'bx;
|
||||
assign o_cmp = i_cmp_neg^(i_cmp_sel ? result_eq : result_lt);
|
||||
|
||||
assign o_rd = (i_op == ALU_OP_ADD) ? result_add :
|
||||
(i_op == ALU_OP_SUB) ? result_add :
|
||||
(i_op == ALU_OP_SR) ? result_sh :
|
||||
assign o_rd = (i_rd_sel == ALU_RESULT_ADD) ? result_add :
|
||||
(i_rd_sel == ALU_RESULT_SR) ? result_sh :
|
||||
1'bx;
|
||||
|
||||
always @(posedge clk)
|
||||
en_r <= i_en;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (i_init)
|
||||
result_lt <= /*v^*/result_add;
|
||||
|
||||
en_r <= i_en;
|
||||
end
|
||||
endmodule
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@ module serv_ctrl
|
||||
input i_en,
|
||||
input i_jump,
|
||||
input i_offset,
|
||||
input i_rs1,
|
||||
input i_jalr,
|
||||
input i_auipc,
|
||||
output o_rd,
|
||||
output [31:0] o_i_ca_adr,
|
||||
@@ -21,6 +23,8 @@ module serv_ctrl
|
||||
wire pc;
|
||||
|
||||
wire new_pc;
|
||||
|
||||
wire offset_a;
|
||||
|
||||
assign plus_4 = en_2r & !en_3r;
|
||||
|
||||
@@ -32,7 +36,8 @@ module serv_ctrl
|
||||
.a (pc),
|
||||
.b (plus_4),
|
||||
.clr (!i_en),
|
||||
.q (pc_plus_4));
|
||||
.q (pc_plus_4),
|
||||
.o_v ());
|
||||
|
||||
shift_reg
|
||||
#(
|
||||
@@ -49,14 +54,17 @@ module serv_ctrl
|
||||
|
||||
assign new_pc = i_jump ? pc_plus_offset : pc_plus_4;
|
||||
assign o_rd = i_auipc ? pc_plus_offset : pc_plus_4;
|
||||
|
||||
assign offset_a = i_jalr ? i_rs1 : pc;
|
||||
|
||||
ser_add ser_add_pc_plus_offset
|
||||
(
|
||||
.clk (clk),
|
||||
.a (pc),
|
||||
.a (offset_a),
|
||||
.b (i_offset),
|
||||
.clr (!i_en),
|
||||
.q (pc_plus_offset));
|
||||
.q (pc_plus_offset),
|
||||
.o_v ());
|
||||
|
||||
reg en_r = 1'b1;
|
||||
reg en_2r = 1'b0;
|
||||
|
||||
@@ -6,6 +6,7 @@ module serv_decode
|
||||
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,
|
||||
@@ -13,10 +14,13 @@ module serv_decode
|
||||
output [4:0] o_rf_rs1_addr,
|
||||
output [4:0] o_rf_rs2_addr,
|
||||
output o_alu_en,
|
||||
output [2:0] o_alu_op,
|
||||
output o_alu_init,
|
||||
output o_alu_sub,
|
||||
output o_alu_cmp_sel,
|
||||
output o_alu_cmp_neg,
|
||||
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,
|
||||
@@ -46,6 +50,7 @@ module serv_decode
|
||||
OP_OP = 5'b01100,
|
||||
OP_LUI = 5'b01101,
|
||||
OP_BRANCH = 5'b11000,
|
||||
OP_JALR = 5'b11001,
|
||||
OP_JAL = 5'b11011;
|
||||
|
||||
reg [2:0] state = 3'd0;
|
||||
@@ -61,8 +66,11 @@ module serv_decode
|
||||
|
||||
assign o_ctrl_en = running;
|
||||
assign o_ctrl_jump = (opcode == OP_JAL) |
|
||||
(opcode == OP_JALR) |
|
||||
((opcode == OP_BRANCH) & i_alu_cmp);
|
||||
|
||||
assign o_ctrl_jalr = (opcode == OP_JALR);
|
||||
|
||||
assign o_ctrl_auipc = (opcode == OP_AUIPC);
|
||||
|
||||
assign o_rf_rd_en = running &
|
||||
@@ -72,17 +80,31 @@ module serv_decode
|
||||
assign o_rf_rs_en = cnt_en /*(running & (opcode == OP_OPIMM)) |
|
||||
(state == SH_INIT) |
|
||||
(state == MEM_INIT)*/;
|
||||
wire sub = (opcode == OP_OP) & i_i_rd_dat[30]; //FIXME: Change for addi?
|
||||
//FIXME: Change for addi?
|
||||
|
||||
assign o_alu_en = cnt_en;
|
||||
assign o_alu_op = (o_funct3 == 3'b000) ? {1'b0, sub, 1'b0} :
|
||||
(o_funct3 == 3'b101) ? ALU_OP_SR :
|
||||
3'bxxx;
|
||||
|
||||
assign o_alu_init = (state == COMPARE) |
|
||||
(state == SH_INIT);
|
||||
|
||||
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_OPIMM) & (o_funct3 == 3'b000)) ? 1'b0 :
|
||||
1'bx;
|
||||
|
||||
assign o_alu_cmp_sel = (o_funct3[2:1] == 2'b00) ? ALU_CMP_EQ :
|
||||
(o_funct3[2] == 1'b1) ? ALU_CMP_LT :
|
||||
(o_funct3[2:1] == 2'b01) ? ALU_CMP_LT : 1'bx;
|
||||
|
||||
assign o_alu_cmp_neg = (opcode == OP_BRANCH) & o_funct3[0];
|
||||
|
||||
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_mem_en = mem_op & cnt_en;
|
||||
assign o_mem_cmd = (opcode == OP_STORE);
|
||||
|
||||
@@ -92,7 +114,11 @@ module serv_decode
|
||||
assign o_funct3 = i_i_rd_dat[14:12];
|
||||
assign o_rf_rs1_addr = i_i_rd_dat[19:15];
|
||||
assign o_rf_rs2_addr = i_i_rd_dat[24:20];
|
||||
assign o_offset_source = (opcode == OP_JAL) ? OFFSET_SOURCE_IMM : 1'b0;
|
||||
assign o_offset_source = (opcode == OP_JAL) ? OFFSET_SOURCE_IMM :
|
||||
(opcode == OP_AUIPC) ? OFFSET_SOURCE_IMM :
|
||||
(opcode == OP_BRANCH) ? OFFSET_SOURCE_IMM :
|
||||
(opcode == OP_JALR) ? OFFSET_SOURCE_IMM :
|
||||
1'bx;
|
||||
|
||||
assign o_op_b_source = (opcode == OP_OPIMM) ? OP_B_SOURCE_IMM :
|
||||
(opcode == OP_BRANCH) ? OP_B_SOURCE_RS2 :
|
||||
@@ -110,6 +136,7 @@ module serv_decode
|
||||
(opcode == OP_OP) ? RD_SOURCE_ALU :
|
||||
(opcode == OP_LUI) ? RD_SOURCE_IMM :
|
||||
(opcode == OP_AUIPC) ? RD_SOURCE_CTRL :
|
||||
(opcode == OP_JALR) ? RD_SOURCE_CTRL :
|
||||
(opcode == OP_LOAD) ? RD_SOURCE_MEM : 2'bxx;
|
||||
|
||||
always @(cnt, opcode, i_i_rd_dat) begin
|
||||
@@ -120,7 +147,7 @@ module serv_decode
|
||||
else if (cnt > 10) o_imm = i_i_rd_dat[20];
|
||||
else if (cnt > 0) o_imm = i_i_rd_dat[cnt+20];
|
||||
else o_imm = 1'b0;
|
||||
else if (opcode == OP_OPIMM)
|
||||
else if ((opcode == OP_OPIMM) | (opcode == OP_JALR))
|
||||
if (cnt > 10) o_imm = i_i_rd_dat[31];
|
||||
else o_imm = i_i_rd_dat[cnt+20];
|
||||
else if ((opcode == OP_LUI) | (opcode == OP_AUIPC))
|
||||
@@ -179,6 +206,7 @@ module serv_decode
|
||||
if (cnt_done)
|
||||
state <= IDLE;
|
||||
end
|
||||
default : state <= 3'bxxx;
|
||||
endcase
|
||||
|
||||
cnt <= cnt + {4'd0,cnt_en};
|
||||
|
||||
@@ -41,7 +41,8 @@ module serv_mem_if
|
||||
.a (i_rs1),
|
||||
.b (i_imm),
|
||||
.clr (!i_en),
|
||||
.q (adr));
|
||||
.q (adr),
|
||||
.o_v ());
|
||||
|
||||
shift_reg #(32) shift_reg_adr
|
||||
(
|
||||
@@ -68,7 +69,7 @@ module serv_mem_if
|
||||
assign o_d_dm_dat = dat;
|
||||
assign o_d_dm_msk = is_word ? 4'b1111 :
|
||||
is_half ? {{2{upper_half}}, ~{2{upper_half}}} :
|
||||
1'b1 << bytepos;
|
||||
4'd1 << bytepos;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
signbit <= dat[0];
|
||||
|
||||
@@ -6,20 +6,27 @@ localparam [1:0]
|
||||
|
||||
localparam [0:0]
|
||||
OFFSET_SOURCE_IMM = 1'd0,
|
||||
OFFSET_SOURCE_RD = 1'd1;
|
||||
OFFSET_SOURCE_RS1 = 1'd1;
|
||||
|
||||
localparam [0:0]
|
||||
OP_B_SOURCE_IMM = 1'd0,
|
||||
OP_B_SOURCE_RS2 = 1'd1;
|
||||
|
||||
localparam[2:0]
|
||||
ALU_OP_ADD = 3'd0,
|
||||
ALU_OP_SL = 3'd1,
|
||||
ALU_OP_SUB = 3'd2,
|
||||
ALU_OP_SLT = 3'd3,
|
||||
ALU_OP_XOR = 3'd4,
|
||||
ALU_OP_SR = 3'd5,
|
||||
ALU_OP_OR = 3'd6,
|
||||
ALU_OP_AND = 3'd7;
|
||||
localparam[1:0]
|
||||
ALU_RESULT_ADD = 2'd0,
|
||||
ALU_RESULT_SR = 2'd1,
|
||||
ALU_RESULT_LT = 2'd2;
|
||||
|
||||
|
||||
localparam [0:0]
|
||||
ALU_CMP_LT = 1'b0,
|
||||
ALU_CMP_EQ = 1'b1;
|
||||
|
||||
/*
|
||||
source
|
||||
ADD, SUB
|
||||
SL,SR
|
||||
SLT
|
||||
XOR,
|
||||
OR
|
||||
AND
|
||||
*/
|
||||
|
||||
@@ -63,6 +63,7 @@ module serv_top
|
||||
|
||||
wire ctrl_en;
|
||||
wire jump;
|
||||
wire jalr;
|
||||
wire auipc;
|
||||
wire offset;
|
||||
wire offset_source;
|
||||
@@ -71,10 +72,13 @@ module serv_top
|
||||
wire [2:0] funct3;
|
||||
|
||||
wire alu_en;
|
||||
wire [2:0] alu_op;
|
||||
wire alu_init;
|
||||
wire alu_sub;
|
||||
wire alu_cmp_sel;
|
||||
wire alu_cmp_neg;
|
||||
wire alu_cmp;
|
||||
wire alu_shamt_en;
|
||||
wire [1:0] alu_rd_sel;
|
||||
|
||||
wire rs1;
|
||||
wire rs2;
|
||||
@@ -102,13 +106,17 @@ module serv_top
|
||||
.o_i_rd_rdy (o_i_rd_rdy),
|
||||
.o_ctrl_en (ctrl_en),
|
||||
.o_ctrl_jump (jump),
|
||||
.o_ctrl_jalr (jalr),
|
||||
.o_ctrl_auipc (auipc),
|
||||
.o_funct3 (funct3),
|
||||
.o_alu_en (alu_en),
|
||||
.o_alu_op (alu_op),
|
||||
.o_alu_init (alu_init),
|
||||
.o_alu_sub (alu_sub),
|
||||
.o_alu_cmp_sel (alu_cmp_sel),
|
||||
.o_alu_cmp_neg (alu_cmp_neg),
|
||||
.i_alu_cmp (alu_cmp),
|
||||
.o_alu_shamt_en (alu_shamt_en),
|
||||
.o_alu_rd_sel (alu_rd_sel),
|
||||
.o_rf_rd_en (rd_en),
|
||||
.o_rf_rd_addr (rd_addr),
|
||||
.o_rf_rs_en (rs_en),
|
||||
@@ -132,13 +140,16 @@ module serv_top
|
||||
.i_en (ctrl_en),
|
||||
.i_jump (jump),
|
||||
.i_offset (offset),
|
||||
.i_rs1 (rs1),
|
||||
.i_jalr (jalr),
|
||||
.i_auipc (auipc),
|
||||
.o_rd (ctrl_rd),
|
||||
.o_i_ca_adr (o_i_ca_adr),
|
||||
.o_i_ca_vld (o_i_ca_vld),
|
||||
.i_i_ca_rdy (i_i_ca_rdy));
|
||||
|
||||
assign offset = (offset_source == OFFSET_SOURCE_IMM) ? imm : rs1;
|
||||
assign offset = (offset_source == OFFSET_SOURCE_IMM) ? imm :
|
||||
(offset_source == OFFSET_SOURCE_RS1) ? rs1 : 1'bx;
|
||||
|
||||
assign rd = (rd_source == RD_SOURCE_CTRL) ? ctrl_rd :
|
||||
(rd_source == RD_SOURCE_ALU) ? alu_rd :
|
||||
@@ -154,13 +165,15 @@ module serv_top
|
||||
(
|
||||
.clk (clk),
|
||||
.i_en (alu_en),
|
||||
.i_op (alu_op),
|
||||
.i_funct3 (funct3),
|
||||
.i_init (alu_init),
|
||||
.o_cmp (alu_cmp),
|
||||
.i_shamt_en (alu_shamt_en),
|
||||
.i_rs1 (rs1),
|
||||
.i_op_b (op_b),
|
||||
.i_init (alu_init),
|
||||
.i_sub (alu_sub),
|
||||
.i_cmp_sel (alu_cmp_sel),
|
||||
.i_cmp_neg (alu_cmp_neg),
|
||||
.o_cmp (alu_cmp),
|
||||
.i_shamt_en (alu_shamt_en),
|
||||
.i_rd_sel (alu_rd_sel),
|
||||
.o_rd (alu_rd));
|
||||
|
||||
serv_regfile regfile
|
||||
|
||||
Reference in New Issue
Block a user