mirror of
https://github.com/olofk/serv.git
synced 2026-04-28 13:07:20 +00:00
bne, srai
This commit is contained in:
@@ -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
|
||||||
|
|||||||
12
rtl/ser_eq.v
12
rtl/ser_eq.v
@@ -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
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 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
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
(
|
(
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user