1
0
mirror of https://github.com/olofk/serv.git synced 2026-04-28 13:07:20 +00:00

bne, srai

This commit is contained in:
Olof Kindgren
2018-10-30 22:41:05 +01:00
parent 66000a77f5
commit 96b1906676
9 changed files with 191 additions and 56 deletions

View File

@@ -63,9 +63,28 @@ module serv_top_tb;
.rd_dat_o (d_rd_dat), .rd_dat_o (d_rd_dat),
.rd_vld_o (d_rd_vld), .rd_vld_o (d_rd_vld),
.rd_rdy_i (d_rd_rdy)); .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(); vlog_tb_utils vtu();
serv_top serv_top
#(.RESET_PC (32'd8)) #(.RESET_PC (32'd8))
dut dut

View File

@@ -1,15 +1,19 @@
`default_nettype none
module ser_eq module ser_eq
( (
input clk, input clk,
input a, input a,
input b, input b,
input clr, input clr,
output q); output reg o_q);
reg eq = 1'b1; reg eq = 1'b1;
assign q = eq & (a == b); wire q = eq & (a == b);
always @(posedge clk) always @(posedge clk) begin
eq <= q | clr; eq <= q | clr;
if (!clr)
o_q <= q;
end
endmodule endmodule

43
rtl/ser_shift.v Normal file
View 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

View File

@@ -3,27 +3,43 @@ module serv_alu
( (
input clk, input clk,
input i_en, input i_en,
input [2:0] i_op,
input [2:0] i_funct3, input [2:0] i_funct3,
input i_rs1, input i_rs1,
input i_op_b, input i_op_b,
input i_cmp_en, input i_init,
output o_cmp, output o_cmp,
input i_shamt_en,
output o_rd); output o_rd);
localparam [2:0] `include "serv_params.vh"
ADDI = 3'b000,
SLTI = 3'b010,
SLTIU = 3'b011,
XORI = 3'b100,
ORI = 3'b110,
ANDI = 3'b111;
localparam[2:0] localparam[2:0]
BEQ = 3'b000; BEQ = 3'b000,
BNE = 3'b001;
wire result_add; wire result_add;
wire result_eq; 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 ser_add ser_add
( (
.clk (clk), .clk (clk),
@@ -32,19 +48,20 @@ module serv_alu
.clr (!i_en), .clr (!i_en),
.q (result_add)); .q (result_add));
reg eq;
ser_eq ser_eq ser_eq ser_eq
( (
.clk (clk), .clk (clk),
.a (i_rs1), .a (i_rs1),
.b (i_op_b), .b (i_op_b),
.clr (!i_cmp_en), .clr (!i_init),
.q (result_eq)); .o_q (result_eq));
assign o_cmp = (i_funct3 == BEQ) ? result_eq : 1'bx;
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 endmodule

View File

@@ -11,8 +11,11 @@ module serv_decode
output o_rf_rs_en, output o_rf_rs_en,
output [4:0] o_rf_rs1_addr, output [4:0] o_rf_rs1_addr,
output [4:0] o_rf_rs2_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, input i_alu_cmp,
output o_alu_shamt_en,
output o_mem_en, output o_mem_en,
output o_mem_cmd, output o_mem_cmd,
output o_mem_init, output o_mem_init,
@@ -26,13 +29,13 @@ module serv_decode
`include "serv_params.vh" `include "serv_params.vh"
localparam [2:0] localparam [2:0]
IDLE = 3'd0, IDLE = 3'd0,
COMPARE = 3'd1, COMPARE = 3'd1,
MEM_INIT = 3'd2, SH_INIT = 3'd2,
MEM_WAIT = 3'd3, MEM_INIT = 3'd3,
RUN = 3'd4; MEM_WAIT = 3'd4,
RUN = 3'd5;
localparam [4:0] localparam [4:0]
OP_LOAD = 5'b00000, OP_LOAD = 5'b00000,
@@ -48,19 +51,33 @@ module serv_decode
wire running; wire running;
wire mem_op; wire mem_op;
wire shift_op;
assign mem_op = (opcode == OP_LOAD) | (opcode == OP_STORE); 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_en = running;
assign o_ctrl_jump = (opcode == OP_JAL) | assign o_ctrl_jump = (opcode == OP_JAL) |
((opcode == OP_BRANCH) & i_alu_cmp); ((opcode == OP_BRANCH) & i_alu_cmp);
assign o_rf_rd_en = running & ((opcode == OP_JAL) | assign o_rf_rd_en = running &
(opcode == OP_OPIMM) | (opcode != OP_STORE) &
(opcode == OP_LUI)); (opcode != OP_BRANCH);
assign o_rf_rs_en = (running & (opcode == OP_OPIMM)) |
(state == MEM_INIT); assign o_rf_rs_en = cnt_en /*(running & (opcode == OP_OPIMM)) |
assign o_alu_cmp_en = (state == COMPARE); (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_en = mem_op & cnt_en;
assign o_mem_cmd = (opcode == OP_STORE); assign o_mem_cmd = (opcode == OP_STORE);
@@ -83,9 +100,10 @@ module serv_decode
assign o_rd_source = (opcode == OP_JAL) ? RD_SOURCE_CTRL : assign o_rd_source = (opcode == OP_JAL) ? RD_SOURCE_CTRL :
(opcode == OP_OPIMM) ? RD_SOURCE_ALU : (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; o_imm = 1'bx;
if (opcode == OP_JAL) if (opcode == OP_JAL)
if (cnt > 19) o_imm = i_i_rd_dat[31]; if (cnt > 19) o_imm = i_i_rd_dat[31];
@@ -119,6 +137,7 @@ module serv_decode
wire cnt_en = wire cnt_en =
(state == RUN) | (state == RUN) |
(state == COMPARE) | (state == COMPARE) |
(state == SH_INIT) |
(state == MEM_INIT); (state == MEM_INIT);
wire cnt_done = cnt == 31; wire cnt_done = cnt == 31;
@@ -129,8 +148,13 @@ module serv_decode
case (state) case (state)
IDLE : begin IDLE : begin
if (go) if (go)
state <= (opcode == OP_BRANCH) ? COMPARE : state <= (opcode == OP_BRANCH) ? COMPARE :
mem_op ? MEM_INIT : RUN; mem_op ? MEM_INIT :
shift_op ? SH_INIT : RUN;
end
SH_INIT : begin
if (cnt_done)
state <= RUN;
end end
COMPARE : begin COMPARE : begin
if (cnt_done) if (cnt_done)

View File

@@ -29,6 +29,7 @@ module serv_mem_if
wire dm_en = o_d_dm_vld & i_d_dm_rdy; wire dm_en = o_d_dm_vld & i_d_dm_rdy;
wire rd_en = i_d_rd_vld & o_d_rd_rdy; wire rd_en = i_d_rd_vld & o_d_rd_rdy;
reg init_r;
reg en_r; reg en_r;
wire adr; wire adr;
reg [31:0] dat = 32'd0; reg [31:0] dat = 32'd0;
@@ -61,7 +62,7 @@ module serv_mem_if
wire is_word = i_funct3[1]; wire is_word = i_funct3[1];
wire is_half = i_funct3[0]; wire is_half = i_funct3[0];
wire is_byte = !(|i_funct3[1: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]; wire upper_half = bytepos[1];
assign o_d_dm_dat = dat; assign o_d_dm_dat = dat;
@@ -88,15 +89,16 @@ module serv_mem_if
end end
en_r <= i_en; en_r <= i_en;
init_r <= i_init;
if (ca_en) if (ca_en)
o_d_ca_vld <= 1'b0; 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; o_d_ca_vld <= 1'b1;
end end
if (dm_en) if (dm_en)
o_d_dm_vld <= 1'b0; o_d_dm_vld <= 1'b0;
else if (en_r & !i_en) else if (init_r & !i_init)
o_d_dm_vld <= i_cmd; o_d_dm_vld <= i_cmd;
if (i_en) if (i_en)

View File

@@ -12,3 +12,14 @@ localparam [0:0]
OP_B_SOURCE_IMM = 1'd0, OP_B_SOURCE_IMM = 1'd0,
OP_B_SOURCE_RS2 = 1'd1; 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;

View File

@@ -1,6 +1,5 @@
`default_nettype none `default_nettype none
`define RISCV_FORMAL
`define RISCV_FORMAL_NRET 1 `define RISCV_FORMAL_NRET 1
`define RISCV_FORMAL_XLEN 32 `define RISCV_FORMAL_XLEN 32
`define RISCV_FORMAL_ILEN 32 `define RISCV_FORMAL_ILEN 32
@@ -70,8 +69,11 @@ module serv_top
wire [2:0] funct3; wire [2:0] funct3;
wire alu_cmp_en; wire alu_en;
wire [2:0] alu_op;
wire alu_init;
wire alu_cmp; wire alu_cmp;
wire alu_shamt_en;
wire rs1; wire rs1;
wire rs2; wire rs2;
@@ -100,8 +102,11 @@ module serv_top
.o_ctrl_en (ctrl_en), .o_ctrl_en (ctrl_en),
.o_ctrl_jump (jump), .o_ctrl_jump (jump),
.o_funct3 (funct3), .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), .i_alu_cmp (alu_cmp),
.o_alu_shamt_en (alu_shamt_en),
.o_rf_rd_en (rd_en), .o_rf_rd_en (rd_en),
.o_rf_rd_addr (rd_addr), .o_rf_rd_addr (rd_addr),
.o_rf_rs_en (rs_en), .o_rf_rs_en (rs_en),
@@ -133,24 +138,27 @@ module serv_top
assign offset = (offset_source == OFFSET_SOURCE_IMM) ? imm : rs1; assign offset = (offset_source == OFFSET_SOURCE_IMM) ? imm : rs1;
assign rd = (rd_source == RD_SOURCE_CTRL) ? ctrl_rd : assign rd = (rd_source == RD_SOURCE_CTRL) ? ctrl_rd :
(rd_source == RD_SOURCE_ALU) ? alu_rd : (rd_source == RD_SOURCE_ALU) ? alu_rd :
(rd_source == RD_SOURCE_IMM) ? imm : (rd_source == RD_SOURCE_IMM) ? imm :
(rd_source == RD_SOURCE_MEM) ? mem_rd : 1'b0; (rd_source == RD_SOURCE_MEM) ? mem_rd : 1'bx;
assign op_b = (op_b_source == OP_B_SOURCE_IMM) ? imm : 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 serv_alu alu
( (
.clk (clk), .clk (clk),
.i_en (ctrl_en), .i_en (alu_en),
.i_funct3 (funct3), .i_op (alu_op),
.i_cmp_en (alu_cmp_en), .i_funct3 (funct3),
.o_cmp (alu_cmp), .i_init (alu_init),
.i_rs1 (rs1), .o_cmp (alu_cmp),
.i_op_b (op_b), .i_shamt_en (alu_shamt_en),
.o_rd (alu_rd)); .i_rs1 (rs1),
.i_op_b (op_b),
.o_rd (alu_rd));
serv_regfile regfile serv_regfile regfile
( (

View File

@@ -10,6 +10,7 @@ filesets:
- rtl/shift_reg.v - rtl/shift_reg.v
- rtl/ser_add.v - rtl/ser_add.v
- rtl/ser_eq.v - rtl/ser_eq.v
- rtl/ser_shift.v
- rtl/serv_alu.v - rtl/serv_alu.v
- rtl/serv_ctrl.v - rtl/serv_ctrl.v
- rtl/serv_decode.v - rtl/serv_decode.v
@@ -77,4 +78,10 @@ targets:
serv_top_tb: serv_top_tb:
default_tool: icarus default_tool: icarus
filesets : [core, serv_top_tb] filesets : [core, serv_top_tb]
parameters : [RISCV_FORMAL=true]
toplevel : serv_top_tb toplevel : serv_top_tb
parameters:
RISCV_FORMAL:
datatype : bool
paramtype : vlogdefine