mirror of
https://github.com/olofk/serv.git
synced 2025-04-22 21:07:12 -04:00
bne, srai
This commit is contained in:
parent
66000a77f5
commit
96b1906676
9 changed files with 191 additions and 56 deletions
|
@ -63,9 +63,28 @@ module serv_top_tb;
|
|||
.rd_dat_o (d_rd_dat),
|
||||
.rd_vld_o (d_rd_vld),
|
||||
.rd_rdy_i (d_rd_rdy));
|
||||
|
||||
reg catch_write = 1'b0;
|
||||
|
||||
reg dbg = 1'b0;
|
||||
|
||||
wire d_ca_en = d_ca_vld & d_ca_rdy;
|
||||
wire d_dm_en = d_dm_vld & d_dm_rdy;
|
||||
|
||||
always @(posedge clk) begin
|
||||
dbg <= 1'b0;
|
||||
|
||||
if (d_ca_en & d_ca_cmd & (d_ca_adr == 32'h10000000))
|
||||
catch_write <= 1'b1;
|
||||
if (catch_write & d_dm_en & d_dm_msk[0]) begin
|
||||
dbg <= 1'b1;
|
||||
$write("%c", d_dm_dat[7:0]);
|
||||
$fflush();
|
||||
catch_write = 1'b0;
|
||||
end
|
||||
end
|
||||
vlog_tb_utils vtu();
|
||||
|
||||
|
||||
serv_top
|
||||
#(.RESET_PC (32'd8))
|
||||
dut
|
||||
|
|
12
rtl/ser_eq.v
12
rtl/ser_eq.v
|
@ -1,15 +1,19 @@
|
|||
`default_nettype none
|
||||
module ser_eq
|
||||
(
|
||||
input clk,
|
||||
input a,
|
||||
input b,
|
||||
input clr,
|
||||
output q);
|
||||
output reg o_q);
|
||||
|
||||
reg eq = 1'b1;
|
||||
|
||||
assign q = eq & (a == b);
|
||||
always @(posedge clk)
|
||||
eq <= q | clr;
|
||||
wire q = eq & (a == b);
|
||||
always @(posedge clk) begin
|
||||
eq <= q | clr;
|
||||
if (!clr)
|
||||
o_q <= q;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
43
rtl/ser_shift.v
Normal file
43
rtl/ser_shift.v
Normal file
|
@ -0,0 +1,43 @@
|
|||
`default_nettype none
|
||||
module ser_shift
|
||||
(
|
||||
input i_clk,
|
||||
input i_load,
|
||||
input [4:0] i_shamt,
|
||||
input i_sr,
|
||||
input i_d,
|
||||
output 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_en (i_load),
|
||||
.i_d (i_d),
|
||||
.o_q (shiftreg[0]),
|
||||
.o_par (shiftreg[31:1]));
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
cnt <= cnt + 1;
|
||||
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];
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
|
|
@ -3,27 +3,43 @@ 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_cmp_en,
|
||||
output o_cmp,
|
||||
input i_init,
|
||||
output o_cmp,
|
||||
input i_shamt_en,
|
||||
output o_rd);
|
||||
|
||||
localparam [2:0]
|
||||
ADDI = 3'b000,
|
||||
SLTI = 3'b010,
|
||||
SLTIU = 3'b011,
|
||||
XORI = 3'b100,
|
||||
ORI = 3'b110,
|
||||
ANDI = 3'b111;
|
||||
`include "serv_params.vh"
|
||||
|
||||
localparam[2:0]
|
||||
BEQ = 3'b000;
|
||||
BEQ = 3'b000,
|
||||
BNE = 3'b001;
|
||||
|
||||
wire result_add;
|
||||
wire result_eq;
|
||||
wire result_sh;
|
||||
|
||||
wire [4:0] shamt;
|
||||
|
||||
shift_reg #(.LEN (5)) shamt_reg
|
||||
(.clk (clk),
|
||||
.i_en (i_shamt_en),
|
||||
.i_d (i_op_b),
|
||||
.o_q (shamt[0]),
|
||||
.o_par (shamt[4:1]));
|
||||
|
||||
ser_shift shift
|
||||
(
|
||||
.i_clk (clk),
|
||||
.i_load (i_init),
|
||||
.i_shamt (shamt),
|
||||
.i_sr (/*FIXME*/),
|
||||
.i_d (i_rs1),
|
||||
.o_q (result_sh));
|
||||
|
||||
ser_add ser_add
|
||||
(
|
||||
.clk (clk),
|
||||
|
@ -32,19 +48,20 @@ 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;
|
||||
.clr (!i_init),
|
||||
.o_q (result_eq));
|
||||
|
||||
assign o_rd = (i_funct3 == ADDI) ? result_add : 1'b0;
|
||||
assign o_cmp = (i_funct3 == BEQ) ? result_eq :
|
||||
(i_funct3 == BNE) ? ~result_eq : 1'bx;
|
||||
|
||||
assign o_rd = (i_op == ALU_OP_ADD) ? result_add :
|
||||
(i_op == ALU_OP_SR) ? result_sh :
|
||||
1'bx;
|
||||
|
||||
endmodule
|
||||
|
||||
|
|
|
@ -11,8 +11,11 @@ module serv_decode
|
|||
output o_rf_rs_en,
|
||||
output [4:0] o_rf_rs1_addr,
|
||||
output [4:0] o_rf_rs2_addr,
|
||||
output o_alu_cmp_en,
|
||||
output o_alu_en,
|
||||
output [2:0] o_alu_op,
|
||||
output o_alu_init,
|
||||
input i_alu_cmp,
|
||||
output o_alu_shamt_en,
|
||||
output o_mem_en,
|
||||
output o_mem_cmd,
|
||||
output o_mem_init,
|
||||
|
@ -26,13 +29,13 @@ module serv_decode
|
|||
|
||||
`include "serv_params.vh"
|
||||
|
||||
|
||||
localparam [2:0]
|
||||
IDLE = 3'd0,
|
||||
COMPARE = 3'd1,
|
||||
MEM_INIT = 3'd2,
|
||||
MEM_WAIT = 3'd3,
|
||||
RUN = 3'd4;
|
||||
SH_INIT = 3'd2,
|
||||
MEM_INIT = 3'd3,
|
||||
MEM_WAIT = 3'd4,
|
||||
RUN = 3'd5;
|
||||
|
||||
localparam [4:0]
|
||||
OP_LOAD = 5'b00000,
|
||||
|
@ -48,19 +51,33 @@ module serv_decode
|
|||
|
||||
wire running;
|
||||
wire mem_op;
|
||||
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 o_ctrl_en = running;
|
||||
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_rf_rd_en = running &
|
||||
(opcode != OP_STORE) &
|
||||
(opcode != OP_BRANCH);
|
||||
|
||||
assign o_rf_rs_en = cnt_en /*(running & (opcode == OP_OPIMM)) |
|
||||
(state == SH_INIT) |
|
||||
(state == MEM_INIT)*/;
|
||||
wire sub = 1'b0; //FIXME
|
||||
|
||||
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_shamt_en = (state == SH_INIT) & (cnt < 5);
|
||||
|
||||
assign o_mem_en = mem_op & cnt_en;
|
||||
assign o_mem_cmd = (opcode == OP_STORE);
|
||||
|
||||
|
@ -83,9 +100,10 @@ module serv_decode
|
|||
|
||||
assign o_rd_source = (opcode == OP_JAL) ? RD_SOURCE_CTRL :
|
||||
(opcode == OP_OPIMM) ? RD_SOURCE_ALU :
|
||||
(opcode == OP_LUI) ? RD_SOURCE_IMM : 2'b00;
|
||||
(opcode == OP_LUI) ? RD_SOURCE_IMM :
|
||||
(opcode == OP_LOAD) ? RD_SOURCE_MEM : 2'bxx;
|
||||
|
||||
always @(cnt, opcode) begin
|
||||
always @(cnt, opcode, i_i_rd_dat) begin
|
||||
o_imm = 1'bx;
|
||||
if (opcode == OP_JAL)
|
||||
if (cnt > 19) o_imm = i_i_rd_dat[31];
|
||||
|
@ -119,6 +137,7 @@ module serv_decode
|
|||
wire cnt_en =
|
||||
(state == RUN) |
|
||||
(state == COMPARE) |
|
||||
(state == SH_INIT) |
|
||||
(state == MEM_INIT);
|
||||
|
||||
wire cnt_done = cnt == 31;
|
||||
|
@ -129,8 +148,13 @@ module serv_decode
|
|||
case (state)
|
||||
IDLE : begin
|
||||
if (go)
|
||||
state <= (opcode == OP_BRANCH) ? COMPARE :
|
||||
mem_op ? MEM_INIT : RUN;
|
||||
state <= (opcode == OP_BRANCH) ? COMPARE :
|
||||
mem_op ? MEM_INIT :
|
||||
shift_op ? SH_INIT : RUN;
|
||||
end
|
||||
SH_INIT : begin
|
||||
if (cnt_done)
|
||||
state <= RUN;
|
||||
end
|
||||
COMPARE : begin
|
||||
if (cnt_done)
|
||||
|
|
|
@ -29,6 +29,7 @@ module serv_mem_if
|
|||
wire dm_en = o_d_dm_vld & i_d_dm_rdy;
|
||||
wire rd_en = i_d_rd_vld & o_d_rd_rdy;
|
||||
|
||||
reg init_r;
|
||||
reg en_r;
|
||||
wire adr;
|
||||
reg [31:0] dat = 32'd0;
|
||||
|
@ -61,7 +62,7 @@ module serv_mem_if
|
|||
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 [1:0] bytepos = o_d_ca_adr[1:0];
|
||||
wire upper_half = bytepos[1];
|
||||
|
||||
assign o_d_dm_dat = dat;
|
||||
|
@ -88,15 +89,16 @@ module serv_mem_if
|
|||
end
|
||||
|
||||
en_r <= i_en;
|
||||
init_r <= i_init;
|
||||
if (ca_en)
|
||||
o_d_ca_vld <= 1'b0;
|
||||
else if (en_r & !i_en) begin
|
||||
else if (init_r & !i_init) begin //Optimize?
|
||||
o_d_ca_vld <= 1'b1;
|
||||
end
|
||||
|
||||
if (dm_en)
|
||||
o_d_dm_vld <= 1'b0;
|
||||
else if (en_r & !i_en)
|
||||
else if (init_r & !i_init)
|
||||
o_d_dm_vld <= i_cmd;
|
||||
|
||||
if (i_en)
|
||||
|
|
|
@ -12,3 +12,14 @@ 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;
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
`default_nettype none
|
||||
|
||||
`define RISCV_FORMAL
|
||||
`define RISCV_FORMAL_NRET 1
|
||||
`define RISCV_FORMAL_XLEN 32
|
||||
`define RISCV_FORMAL_ILEN 32
|
||||
|
@ -70,8 +69,11 @@ module serv_top
|
|||
|
||||
wire [2:0] funct3;
|
||||
|
||||
wire alu_cmp_en;
|
||||
wire alu_en;
|
||||
wire [2:0] alu_op;
|
||||
wire alu_init;
|
||||
wire alu_cmp;
|
||||
wire alu_shamt_en;
|
||||
|
||||
wire rs1;
|
||||
wire rs2;
|
||||
|
@ -100,8 +102,11 @@ module serv_top
|
|||
.o_ctrl_en (ctrl_en),
|
||||
.o_ctrl_jump (jump),
|
||||
.o_funct3 (funct3),
|
||||
.o_alu_cmp_en (alu_cmp_en),
|
||||
.o_alu_en (alu_en),
|
||||
.o_alu_op (alu_op),
|
||||
.o_alu_init (alu_init),
|
||||
.i_alu_cmp (alu_cmp),
|
||||
.o_alu_shamt_en (alu_shamt_en),
|
||||
.o_rf_rd_en (rd_en),
|
||||
.o_rf_rd_addr (rd_addr),
|
||||
.o_rf_rs_en (rs_en),
|
||||
|
@ -133,24 +138,27 @@ module serv_top
|
|||
assign offset = (offset_source == OFFSET_SOURCE_IMM) ? imm : rs1;
|
||||
|
||||
assign rd = (rd_source == RD_SOURCE_CTRL) ? ctrl_rd :
|
||||
(rd_source == RD_SOURCE_ALU) ? alu_rd :
|
||||
(rd_source == RD_SOURCE_IMM) ? imm :
|
||||
(rd_source == RD_SOURCE_MEM) ? mem_rd : 1'b0;
|
||||
(rd_source == RD_SOURCE_ALU) ? alu_rd :
|
||||
(rd_source == RD_SOURCE_IMM) ? imm :
|
||||
(rd_source == RD_SOURCE_MEM) ? mem_rd : 1'bx;
|
||||
|
||||
|
||||
assign op_b = (op_b_source == OP_B_SOURCE_IMM) ? imm :
|
||||
1'b0;
|
||||
(op_b_source == OP_B_SOURCE_RS2) ? rs2 :
|
||||
1'bx;
|
||||
|
||||
serv_alu alu
|
||||
(
|
||||
.clk (clk),
|
||||
.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));
|
||||
.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),
|
||||
.o_rd (alu_rd));
|
||||
|
||||
serv_regfile regfile
|
||||
(
|
||||
|
|
|
@ -10,6 +10,7 @@ filesets:
|
|||
- rtl/shift_reg.v
|
||||
- rtl/ser_add.v
|
||||
- rtl/ser_eq.v
|
||||
- rtl/ser_shift.v
|
||||
- rtl/serv_alu.v
|
||||
- rtl/serv_ctrl.v
|
||||
- rtl/serv_decode.v
|
||||
|
@ -77,4 +78,10 @@ targets:
|
|||
serv_top_tb:
|
||||
default_tool: icarus
|
||||
filesets : [core, serv_top_tb]
|
||||
parameters : [RISCV_FORMAL=true]
|
||||
toplevel : serv_top_tb
|
||||
|
||||
parameters:
|
||||
RISCV_FORMAL:
|
||||
datatype : bool
|
||||
paramtype : vlogdefine
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue