mirror of
https://github.com/olofk/serv.git
synced 2025-04-22 04:47:16 -04:00
beq, sw
This commit is contained in:
parent
c2030a95fd
commit
66000a77f5
6 changed files with 209 additions and 48 deletions
15
rtl/ser_eq.v
Normal file
15
rtl/ser_eq.v
Normal file
|
@ -0,0 +1,15 @@
|
|||
module ser_eq
|
||||
(
|
||||
input clk,
|
||||
input a,
|
||||
input b,
|
||||
input clr,
|
||||
output q);
|
||||
|
||||
reg eq = 1'b1;
|
||||
|
||||
assign q = eq & (a == b);
|
||||
always @(posedge clk)
|
||||
eq <= q | clr;
|
||||
|
||||
endmodule
|
|
@ -6,6 +6,8 @@ module serv_alu
|
|||
input [2:0] i_funct3,
|
||||
input i_rs1,
|
||||
input i_op_b,
|
||||
input i_cmp_en,
|
||||
output o_cmp,
|
||||
output o_rd);
|
||||
|
||||
localparam [2:0]
|
||||
|
@ -16,7 +18,11 @@ module serv_alu
|
|||
ORI = 3'b110,
|
||||
ANDI = 3'b111;
|
||||
|
||||
localparam[2:0]
|
||||
BEQ = 3'b000;
|
||||
|
||||
wire result_add;
|
||||
wire result_eq;
|
||||
|
||||
ser_add ser_add
|
||||
(
|
||||
|
@ -26,7 +32,19 @@ module serv_alu
|
|||
.clr (!i_en),
|
||||
.q (result_add));
|
||||
|
||||
reg eq;
|
||||
|
||||
ser_eq ser_eq
|
||||
(
|
||||
.clk (clk),
|
||||
.a (i_rs1),
|
||||
.b (i_op_b),
|
||||
.clr (!i_cmp_en),
|
||||
.q (result_eq));
|
||||
|
||||
assign o_cmp = (i_funct3 == BEQ) ? result_eq : 1'bx;
|
||||
|
||||
assign o_rd = (i_funct3 == ADDI) ? result_add : 1'b0;
|
||||
|
||||
endmodule
|
||||
endmodule
|
||||
|
||||
|
|
|
@ -6,16 +6,19 @@ module serv_decode
|
|||
output reg o_i_rd_rdy = 1'b1,
|
||||
output o_ctrl_en,
|
||||
output o_ctrl_jump,
|
||||
output [2:0] o_funct3,
|
||||
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_cmp_en,
|
||||
input i_alu_cmp,
|
||||
output o_mem_en,
|
||||
output o_mem_cmd,
|
||||
output o_mem_init,
|
||||
output 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,
|
||||
|
@ -24,35 +27,43 @@ module serv_decode
|
|||
`include "serv_params.vh"
|
||||
|
||||
|
||||
localparam [1:0]
|
||||
IDLE = 2'd0,
|
||||
MEM_INIT = 2'd1,
|
||||
MEM_WAIT = 2'd2,
|
||||
RUN = 2'd3;
|
||||
localparam [2:0]
|
||||
IDLE = 3'd0,
|
||||
COMPARE = 3'd1,
|
||||
MEM_INIT = 3'd2,
|
||||
MEM_WAIT = 3'd3,
|
||||
RUN = 3'd4;
|
||||
|
||||
localparam [4:0]
|
||||
OP_LOAD = 5'b00000,
|
||||
OP_OPIMM = 5'b00100,
|
||||
OP_LUI = 5'b01101,
|
||||
OP_JAL = 5'b11011;
|
||||
OP_LOAD = 5'b00000,
|
||||
OP_STORE = 5'b01000,
|
||||
OP_OPIMM = 5'b00100,
|
||||
OP_LUI = 5'b01101,
|
||||
OP_BRANCH = 5'b11000,
|
||||
OP_JAL = 5'b11011;
|
||||
|
||||
reg [2:0] state = 3'd0;
|
||||
|
||||
reg [1:0] state = 2'd0;
|
||||
|
||||
reg [4:0] cnt = 5'd0;
|
||||
|
||||
wire running;
|
||||
wire mem_op;
|
||||
assign mem_op = (opcode == OP_LOAD);
|
||||
assign mem_op = (opcode == OP_LOAD) | (opcode == OP_STORE);
|
||||
|
||||
assign o_ctrl_en = running;
|
||||
assign o_ctrl_jump = (opcode == OP_JAL);
|
||||
assign o_ctrl_jump = (opcode == OP_JAL) |
|
||||
((opcode == OP_BRANCH) & i_alu_cmp);
|
||||
|
||||
assign o_rf_rd_en = running & ((opcode == OP_JAL) |
|
||||
(opcode == OP_OPIMM) |
|
||||
(opcode == OP_LUI));
|
||||
assign o_rf_rs_en = (running & (opcode == OP_OPIMM)) |
|
||||
(state == MEM_INIT);
|
||||
assign o_alu_cmp_en = (state == COMPARE);
|
||||
|
||||
assign o_mem_en = mem_op & cnt_en;
|
||||
assign o_mem_cmd = (opcode == OP_STORE);
|
||||
|
||||
assign o_mem_init = (state == MEM_INIT);
|
||||
|
||||
assign o_rf_rd_addr = i_i_rd_dat[11:7];
|
||||
|
@ -61,7 +72,8 @@ module serv_decode
|
|||
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_op_b_source = (opcode == OP_OPIMM) ? OP_B_SOURCE_IMM : 1'b0;
|
||||
assign o_op_b_source = (opcode == OP_OPIMM) ? OP_B_SOURCE_IMM :
|
||||
(opcode == OP_BRANCH) ? OP_B_SOURCE_RS2 : 1'bx;
|
||||
|
||||
assign o_mem_dat_valid = (o_funct3[1:0] == 2'b00) ? cnt < 8 :
|
||||
(o_funct3[1:0] == 2'b01) ? cnt < 16 : 1'b1;
|
||||
|
@ -90,11 +102,24 @@ module serv_decode
|
|||
else if (opcode == OP_LOAD)
|
||||
if (cnt > 10) o_imm = i_i_rd_dat[31];
|
||||
else o_imm = i_i_rd_dat[cnt+20];
|
||||
else if (opcode == OP_BRANCH)
|
||||
if (cnt > 11) o_imm = i_i_rd_dat[31];
|
||||
else if (cnt > 10) o_imm = i_i_rd_dat[7];
|
||||
else if (cnt > 4) o_imm = i_i_rd_dat[cnt+20];
|
||||
else if (cnt > 0) o_imm = i_i_rd_dat[cnt+7];
|
||||
else o_imm = 1'b0;
|
||||
else if (opcode == OP_STORE)
|
||||
if (cnt > 10) o_imm = i_i_rd_dat[31];
|
||||
else if (cnt > 4) o_imm = i_i_rd_dat[cnt+20];
|
||||
else o_imm = i_i_rd_dat[cnt+7];
|
||||
end
|
||||
|
||||
wire go = i_i_rd_vld & o_i_rd_rdy;
|
||||
|
||||
wire cnt_en = (state == RUN) | (state == MEM_INIT);
|
||||
wire cnt_en =
|
||||
(state == RUN) |
|
||||
(state == COMPARE) |
|
||||
(state == MEM_INIT);
|
||||
|
||||
wire cnt_done = cnt == 31;
|
||||
assign running = (state == RUN);
|
||||
|
@ -104,7 +129,12 @@ module serv_decode
|
|||
case (state)
|
||||
IDLE : begin
|
||||
if (go)
|
||||
state <= mem_op ? MEM_INIT : RUN;
|
||||
state <= (opcode == OP_BRANCH) ? COMPARE :
|
||||
mem_op ? MEM_INIT : RUN;
|
||||
end
|
||||
COMPARE : begin
|
||||
if (cnt_done)
|
||||
state <= RUN;
|
||||
end
|
||||
MEM_INIT :
|
||||
if (cnt_done)
|
||||
|
|
|
@ -19,12 +19,16 @@ module serv_mem_if
|
|||
input i_d_ca_rdy,
|
||||
output [31:0] o_d_dm_dat,
|
||||
output [3:0] o_d_dm_msk,
|
||||
output o_d_dm_vld,
|
||||
output reg o_d_dm_vld = 1'b0,
|
||||
input i_d_dm_rdy,
|
||||
input [31:0] i_d_rd_dat,
|
||||
input i_d_rd_vld,
|
||||
output o_d_rd_rdy);
|
||||
|
||||
wire ca_en = o_d_ca_vld & i_d_ca_rdy;
|
||||
wire dm_en = o_d_dm_vld & i_d_dm_rdy;
|
||||
wire rd_en = i_d_rd_vld & o_d_rd_rdy;
|
||||
|
||||
reg en_r;
|
||||
wire adr;
|
||||
reg [31:0] dat = 32'd0;
|
||||
|
@ -54,17 +58,26 @@ module serv_mem_if
|
|||
|
||||
assign o_d_rd_rdy = !i_en; //Likely bug, but probably doesn't matter
|
||||
|
||||
wire is_half = i_funct3[1];
|
||||
wire is_word = i_funct3[1];
|
||||
wire is_half = i_funct3[0];
|
||||
wire is_byte = !(|i_funct3[1:0]);
|
||||
wire [1:0] bytepos = o_d_ca_adr[3:2];
|
||||
wire upper_half = bytepos[1];
|
||||
|
||||
|
||||
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;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
signbit <= dat[0];
|
||||
|
||||
if (i_en & i_init)
|
||||
o_busy <= 1'b1;
|
||||
else if (i_d_rd_vld & o_d_rd_rdy) begin
|
||||
else if (rd_en | dm_en)
|
||||
o_busy <= 1'b0;
|
||||
|
||||
if (rd_en) begin
|
||||
dat[31:16] <= i_d_rd_dat[31:16];
|
||||
dat[15:8] <= (is_half & upper_half) ? i_d_rd_dat[31:24] : i_d_rd_dat[15:8];
|
||||
dat[7:0] <= (is_byte & (bytepos == 2'b11)) ? i_d_rd_dat[31:24] :
|
||||
|
@ -72,15 +85,20 @@ module serv_mem_if
|
|||
(is_half & upper_half) ? i_d_rd_dat[23:16] :
|
||||
(is_byte & (bytepos == 2'b01)) ? i_d_rd_dat[15:8] :
|
||||
i_d_rd_dat[7:0];
|
||||
o_busy <= 1'b0;
|
||||
end
|
||||
|
||||
en_r <= i_en;
|
||||
if (o_d_ca_vld & i_d_ca_rdy)
|
||||
if (ca_en)
|
||||
o_d_ca_vld <= 1'b0;
|
||||
else if (en_r & !i_en)
|
||||
o_d_ca_vld <= 1'b1;
|
||||
else if (en_r & !i_en) begin
|
||||
o_d_ca_vld <= 1'b1;
|
||||
end
|
||||
|
||||
if (dm_en)
|
||||
o_d_dm_vld <= 1'b0;
|
||||
else if (en_r & !i_en)
|
||||
o_d_dm_vld <= i_cmd;
|
||||
|
||||
if (i_en)
|
||||
dat <= {i_rs2,dat[31:1]};
|
||||
end
|
||||
|
|
121
rtl/serv_top.v
121
rtl/serv_top.v
|
@ -1,24 +1,54 @@
|
|||
`default_nettype none
|
||||
|
||||
`define RISCV_FORMAL
|
||||
`define RISCV_FORMAL_NRET 1
|
||||
`define RISCV_FORMAL_XLEN 32
|
||||
`define RISCV_FORMAL_ILEN 32
|
||||
//`define RISCV_FORMAL_COMPRESSED
|
||||
`define RISCV_FORMAL_ALIGNED_MEM
|
||||
|
||||
module serv_top
|
||||
(
|
||||
input clk,
|
||||
output [31:0] o_i_ca_adr,
|
||||
output o_i_ca_vld,
|
||||
input i_i_ca_rdy,
|
||||
input [31:0] i_i_rd_dat,
|
||||
input i_i_rd_vld,
|
||||
output o_i_rd_rdy,
|
||||
output o_d_ca_cmd,
|
||||
output [31:0] o_d_ca_adr,
|
||||
output o_d_ca_vld,
|
||||
input i_d_ca_rdy,
|
||||
output [31:0] o_d_dm_dat,
|
||||
output [3:0] o_d_dm_msk,
|
||||
output o_d_dm_vld,
|
||||
input i_d_dm_rdy,
|
||||
input [31:0] i_d_rd_dat,
|
||||
input i_d_rd_vld,
|
||||
output o_d_rd_rdy);
|
||||
input clk,
|
||||
`ifdef RISCV_FORMAL
|
||||
output reg rvfi_valid = 1'b0,
|
||||
output reg [63:0] rvfi_order = 64'd0,
|
||||
output reg [31:0] rvfi_insn = 32'd0,
|
||||
output reg rvfi_trap = 1'b0,
|
||||
output reg rvfi_halt = 1'b0,
|
||||
output reg rvfi_intr = 1'b0,
|
||||
output reg [1:0] rvfi_mode = 2'b11,
|
||||
output reg [4:0] rvfi_rs1_addr,
|
||||
output reg [4:0] rvfi_rs2_addr,
|
||||
output reg [31:0] rvfi_rs1_rdata,
|
||||
output reg [31:0] rvfi_rs2_rdata,
|
||||
output reg [4:0] rvfi_rd_addr,
|
||||
output reg [31:0] rvfi_rd_wdata,
|
||||
output reg [31:0] rvfi_pc_rdata,
|
||||
output reg [31:0] rvfi_pc_wdata,
|
||||
output reg [31:0] rvfi_mem_addr,
|
||||
output reg [3:0] rvfi_mem_rmask,
|
||||
output reg [3:0] rvfi_mem_wmask,
|
||||
output reg [31:0] rvfi_mem_rdata,
|
||||
output reg [31:0] rvfi_mem_wdata,
|
||||
`endif
|
||||
output [31:0] o_i_ca_adr,
|
||||
output o_i_ca_vld,
|
||||
input i_i_ca_rdy,
|
||||
input [31:0] i_i_rd_dat,
|
||||
input i_i_rd_vld,
|
||||
output o_i_rd_rdy,
|
||||
output o_d_ca_cmd,
|
||||
output [31:0] o_d_ca_adr,
|
||||
output o_d_ca_vld,
|
||||
input i_d_ca_rdy,
|
||||
output [31:0] o_d_dm_dat,
|
||||
output [3:0] o_d_dm_msk,
|
||||
output o_d_dm_vld,
|
||||
input i_d_dm_rdy,
|
||||
input [31:0] i_d_rd_dat,
|
||||
input i_d_rd_vld,
|
||||
output o_d_rd_rdy);
|
||||
|
||||
`include "serv_params.vh"
|
||||
|
||||
|
@ -39,6 +69,9 @@ module serv_top
|
|||
wire imm;
|
||||
|
||||
wire [2:0] funct3;
|
||||
|
||||
wire alu_cmp_en;
|
||||
wire alu_cmp;
|
||||
|
||||
wire rs1;
|
||||
wire rs2;
|
||||
|
@ -50,7 +83,7 @@ module serv_top
|
|||
|
||||
wire mem_en;
|
||||
|
||||
wire mem_cmd = 1'b0 /*FIXME*/;
|
||||
wire mem_cmd;
|
||||
wire mem_dat_valid;
|
||||
|
||||
wire mem_init;
|
||||
|
@ -67,12 +100,15 @@ module serv_top
|
|||
.o_ctrl_en (ctrl_en),
|
||||
.o_ctrl_jump (jump),
|
||||
.o_funct3 (funct3),
|
||||
.o_alu_cmp_en (alu_cmp_en),
|
||||
.i_alu_cmp (alu_cmp),
|
||||
.o_rf_rd_en (rd_en),
|
||||
.o_rf_rd_addr (rd_addr),
|
||||
.o_rf_rs_en (rs_en),
|
||||
.o_rf_rs1_addr (rs1_addr),
|
||||
.o_rf_rs2_addr (rs2_addr),
|
||||
.o_mem_en (mem_en),
|
||||
.o_mem_cmd (mem_cmd),
|
||||
.o_mem_init (mem_init),
|
||||
.o_mem_dat_valid (mem_dat_valid),
|
||||
.i_mem_busy (mem_busy),
|
||||
|
@ -108,8 +144,10 @@ module serv_top
|
|||
serv_alu alu
|
||||
(
|
||||
.clk (clk),
|
||||
.i_en (ctrl_en), /*FIXME: Is this true?*/
|
||||
.i_en (ctrl_en),
|
||||
.i_funct3 (funct3),
|
||||
.i_cmp_en (alu_cmp_en),
|
||||
.o_cmp (alu_cmp),
|
||||
.i_rs1 (rs1),
|
||||
.i_op_b (op_b),
|
||||
.o_rd (alu_rd));
|
||||
|
@ -139,7 +177,7 @@ module serv_top
|
|||
.i_imm (imm),
|
||||
.o_rd (mem_rd),
|
||||
.o_busy (mem_busy),
|
||||
//External interface
|
||||
//External interface
|
||||
.o_d_ca_cmd (o_d_ca_cmd),
|
||||
.o_d_ca_adr (o_d_ca_adr),
|
||||
.o_d_ca_vld (o_d_ca_vld),
|
||||
|
@ -152,4 +190,45 @@ module serv_top
|
|||
.i_d_rd_vld (i_d_rd_vld),
|
||||
.o_d_rd_rdy (o_d_rd_rdy));
|
||||
|
||||
`ifdef RISCV_FORMAL
|
||||
reg [31:0] rs1_fv, rs2_fv, rd_fv;
|
||||
reg [31:0] pc = RESET_PC;
|
||||
reg ctrl_en_r = 1'b0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
ctrl_en_r <= ctrl_en;
|
||||
if (rs_en) begin
|
||||
rs1_fv <= {rs1,rs1_fv[31:1]};
|
||||
rs2_fv <= {rs2,rs2_fv[31:1]};
|
||||
end
|
||||
if (rd_en) begin
|
||||
rd_fv <= {rd,rd_fv[31:1]};
|
||||
end
|
||||
rvfi_valid <= 1'b0;
|
||||
if (ctrl_en_r & !ctrl_en) begin
|
||||
pc <= o_i_ca_adr;
|
||||
rvfi_valid <= 1'b1;
|
||||
rvfi_order <= rvfi_order + 1;
|
||||
rvfi_insn <= i_i_rd_dat;
|
||||
rvfi_trap <= 1'b0;
|
||||
rvfi_halt <= 1'b0;
|
||||
rvfi_intr <= 1'b0;
|
||||
rvfi_mode <= 2'd3;
|
||||
rvfi_rs1_addr <= rs1_addr;
|
||||
rvfi_rs2_addr <= rs2_addr;
|
||||
rvfi_rs1_rdata <= rs1_fv;
|
||||
rvfi_rs2_rdata <= rs2_fv;
|
||||
rvfi_rd_addr <= rd_addr;
|
||||
rvfi_rd_wdata <= rd_fv;
|
||||
rvfi_pc_rdata <= pc;
|
||||
rvfi_pc_wdata <= o_i_ca_adr;
|
||||
rvfi_mem_addr <= o_d_ca_adr;
|
||||
rvfi_mem_rmask <= 4'bxxxx;
|
||||
rvfi_mem_wmask <= o_d_dm_msk;
|
||||
rvfi_mem_rdata <= i_d_rd_dat;
|
||||
rvfi_mem_wdata <= o_d_dm_dat;
|
||||
end
|
||||
end
|
||||
`endif
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -9,6 +9,7 @@ filesets:
|
|||
- rtl/serv_params.vh : {is_include_file : true}
|
||||
- rtl/shift_reg.v
|
||||
- rtl/ser_add.v
|
||||
- rtl/ser_eq.v
|
||||
- rtl/serv_alu.v
|
||||
- rtl/serv_ctrl.v
|
||||
- rtl/serv_decode.v
|
||||
|
@ -16,7 +17,7 @@ filesets:
|
|||
- rtl/serv_regfile.v
|
||||
- rtl/serv_top.v
|
||||
file_type : verilogSource
|
||||
depend : [wb_ram]
|
||||
depend : [wb_ram, "yosys:techlibs:ice40"]
|
||||
|
||||
ser_add_tb:
|
||||
files:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue