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_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

View file

@ -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
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 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

View file

@ -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)

View file

@ -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)

View file

@ -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;

View file

@ -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
(

View file

@ -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