1
0
mirror of https://github.com/olofk/serv.git synced 2026-01-26 11:41:51 +00:00

Use custom interconnect. Runs on hw

This commit is contained in:
Olof Kindgren
2018-11-21 12:55:44 +01:00
parent 6e034361d4
commit 9df2a0060b
17 changed files with 2407 additions and 261 deletions

View File

@@ -1,43 +1,21 @@
`default_nettype none
module riscv_timer
(input wire i_clk,
output reg o_irq = 1'b0,
input wire [31:0] i_wb_adr,
input wire [31:0] i_wb_dat,
input wire [3:0] i_wb_sel,
input wire i_wb_we,
input wire i_wb_cyc,
input wire i_wb_stb,
output reg [31:0] o_wb_dat,
output reg o_wb_ack = 1'b0);
output reg o_irq = 1'b0,
input wire [31:0] i_wb_dat,
input wire i_wb_we,
input wire i_wb_cyc,
output wire [31:0] o_wb_dat);
reg [63:0] mtime = 64'd0;
reg [63:0] mtimecmp = 64'd0;
reg [31:0] mtime = 32'd0;
reg [31:0] mtimecmp = 32'd0;
localparam [1:0]
REG_MTIMELO = 2'd0,
REG_MTIMEHI = 2'd1,
REG_MTIMECMPLO = 2'd2,
REG_MTIMECMPHI = 2'd3;
always @(i_wb_adr, mtime, mtimecmp)
case (i_wb_adr[3:2])
REG_MTIMELO : o_wb_dat = mtime[31:0];
REG_MTIMEHI : o_wb_dat = mtime[63:32];
REG_MTIMECMPLO : o_wb_dat = mtimecmp[31:0];
REG_MTIMECMPHI : o_wb_dat = mtimecmp[63:32];
endcase
assign o_wb_dat = mtime;
always @(posedge i_clk) begin
o_wb_ack <= 1'b0;
if (i_wb_cyc & i_wb_stb) begin
o_wb_ack <= !o_wb_ack;
if (i_wb_we & (i_wb_adr[3:2] == REG_MTIMECMPLO))
mtimecmp[31:0] <= i_wb_dat;
if (i_wb_we & (i_wb_adr[3:2] == REG_MTIMECMPHI))
mtimecmp[63:32] <= i_wb_dat;
end
mtime <= mtime + 64'd1;
if (i_wb_cyc & i_wb_we)
mtimecmp <= i_wb_dat;
mtime <= mtime + 32'd1;
o_irq <= (mtime >= mtimecmp);
end
endmodule

View File

@@ -2,18 +2,24 @@
module ser_add
(
input wire clk,
input wire rst,
input wire a,
input wire b,
input wire clr,
output wire q,
output wire o_v);
reg c_r = 1'b0;
reg c_r;
assign o_v = (a&b | a&c_r | b&c_r);
wire axorb = a^b;
assign q = a ^ b ^ c_r;
assign o_v = (axorb & c_r) | (a&b);
assign q = axorb ^ c_r;
always @(posedge clk)
c_r <= !clr & o_v;
if (rst)
c_r <= 1'b0;
else
c_r <= !clr & o_v;
endmodule

View File

@@ -2,6 +2,7 @@
module serv_alu
(
input wire clk,
input wire i_rst,
input wire i_en,
input wire i_rs1,
input wire i_op_b,
@@ -36,6 +37,7 @@ module serv_alu
ser_add ser_add_inv_shamt_plus1
(
.clk (clk),
.rst (i_rst),
.a (~i_op_b),
.b (plus_1),
.clr (!i_en),
@@ -67,6 +69,7 @@ module serv_alu
ser_add ser_add_inv_plus_1
(
.clk (clk),
.rst (i_rst),
.a (~i_op_b),
.b (plus_1),
.clr (!i_en),
@@ -78,6 +81,7 @@ module serv_alu
ser_add ser_add
(
.clk (clk),
.rst (i_rst),
.a (i_rs1),
.b (add_b),
.clr (!i_en),

View File

@@ -11,6 +11,7 @@ module serv_ctrl
input wire i_rs1,
input wire i_jalr,
input wire i_auipc,
input wire i_lui,
input wire i_trap,
input wire i_csr_pc,
output wire o_rd,
@@ -41,6 +42,7 @@ module serv_ctrl
ser_add ser_add_pc_plus_4
(
.clk (clk),
.rst (i_rst),
.a (pc),
.b (plus_4),
.clr (i_cnt_done),
@@ -61,13 +63,14 @@ module serv_ctrl
);
assign new_pc = i_trap ? (i_csr_pc & en_pc_r) : i_jump ? pc_plus_offset_aligned : pc_plus_4;
assign o_rd = i_auipc ? pc_plus_offset_aligned : pc_plus_4;
assign o_rd = i_lui ? i_offset : i_auipc ? pc_plus_offset_aligned : pc_plus_4;
assign offset_a = i_jalr ? i_rs1 : pc;
ser_add ser_add_pc_plus_offset
(
.clk (clk),
.rst (i_rst),
.a (offset_a),
.b (i_offset),
.clr (i_cnt_done),

View File

@@ -12,6 +12,7 @@ module serv_decode
output wire o_ctrl_jump,
output wire o_ctrl_jalr,
output wire o_ctrl_auipc,
output wire o_ctrl_lui,
output wire o_ctrl_trap,
output wire o_ctrl_mret,
input wire i_ctrl_misalign,
@@ -44,10 +45,9 @@ module serv_decode
output wire o_csr_imm,
output wire o_csr_d_sel,
output reg [2:0] o_funct3,
output reg o_imm,
output wire o_offset_source,
output wire o_imm,
output wire o_op_b_source,
output wire [2:0] o_rd_source);
output wire [1:0] o_rd_source);
`include "serv_params.vh"
@@ -83,7 +83,7 @@ module serv_decode
wire e_op;
wire jump_misaligned;
reg signbit;
reg imm30;
assign o_cnt_done = cnt_done;
@@ -119,16 +119,17 @@ module serv_decode
assign o_alu_en = cnt_en;
assign o_ctrl_lui = opcode == OP_LUI;
assign o_ctrl_en = cnt_en;
assign o_alu_init = (state == INIT);
assign o_alu_sub = (opcode == OP_OP) ? signbit /* ? 1'b1*/ :
assign o_alu_sub = (opcode == OP_OP) ? imm30 /* ? 1'b1*/ :
(branch_op & (o_funct3 == 3'b100)) ? 1'b1 :
(branch_op & (o_funct3 == 3'b101)) ? 1'b1 :
(branch_op & (o_funct3 == 3'b110)) ? 1'b1 :
((opcode == OP_OPIMM) & (o_funct3 == 3'b000)) ? 1'b0 :
1'bx;
1'b0;
assign o_alu_cmp_neg = branch_op & o_funct3[0];
@@ -198,11 +199,11 @@ module serv_decode
assign o_csr_d_sel = o_funct3[2];
assign o_alu_shamt_en = (cnt < 5) & (state == INIT);
assign o_alu_sh_signed = signbit;
assign o_alu_sh_signed = imm30;
assign o_alu_sh_right = o_funct3[2];
assign o_mem_en = mem_op & cnt_en;
assign o_mem_cmd = (opcode == OP_STORE);
assign o_mem_cmd = opcode[3];
assign o_mem_init = mem_op & (state == INIT);
@@ -210,6 +211,7 @@ module serv_decode
reg [4:0] opcode;
reg [31:0] imm;
reg signbit;
always @(posedge clk) begin
if (i_wb_en) begin
@@ -217,74 +219,67 @@ module serv_decode
o_rf_rs1_addr <= i_wb_rdt[19:15];
o_rf_rs2_addr <= i_wb_rdt[24:20];
o_funct3 <= i_wb_rdt[14:12];
signbit <= i_wb_rdt[30];
imm30 <= i_wb_rdt[30];
opcode <= i_wb_rdt[6:2];
imm <= i_wb_rdt;
signbit <= imm[31];
end
end
assign o_offset_source = (opcode == OP_JAL) ? OFFSET_SOURCE_IMM :
(opcode == OP_AUIPC) ? OFFSET_SOURCE_IMM :
(opcode == OP_BRANCH) ? OFFSET_SOURCE_IMM :
(opcode == OP_JALR) ? OFFSET_SOURCE_IMM :
1'bx;
assign o_op_b_source = (opcode == OP_OPIMM) ? OP_B_SOURCE_IMM :
(opcode == OP_BRANCH) ? OP_B_SOURCE_RS2 :
(opcode == OP_OP) ? OP_B_SOURCE_RS2 :
1'bx;
always @(o_funct3, cnt, o_mem_init)
if (o_mem_init)
o_mem_dat_valid = 1'bx;
else
casez(o_funct3[1:0])
2'b00 : o_mem_dat_valid = (cnt < 8);
2'b01 : o_mem_dat_valid = (cnt < 16);
2'b10 : o_mem_dat_valid = 1'b1;
default: o_mem_dat_valid = 1'bx;
endcase
always @(o_funct3, cnt) begin
o_mem_dat_valid = 1'b0;
casez(o_funct3[1:0])
2'b00 : o_mem_dat_valid = (cnt < 8);
2'b01 : o_mem_dat_valid = (cnt < 16);
2'b10 : o_mem_dat_valid = 1'b1;
default: o_mem_dat_valid = 1'b0;
endcase
end
assign o_rd_source = (opcode == OP_JAL) ? RD_SOURCE_CTRL :
(opcode == OP_OPIMM) ? RD_SOURCE_ALU :
(opcode == OP_OP) ? RD_SOURCE_ALU :
(opcode == OP_LUI) ? RD_SOURCE_IMM :
(opcode == OP_LUI) ? RD_SOURCE_CTRL :
(opcode == OP_AUIPC) ? RD_SOURCE_CTRL :
(opcode == OP_JALR) ? RD_SOURCE_CTRL :
(opcode == OP_SYSTEM) ? RD_SOURCE_CSR :
(opcode == OP_LOAD) ? RD_SOURCE_MEM : 3'bxx;
RD_SOURCE_MEM;
//31, cnt, 20, +20, +7, 7, 1'b0
always @(cnt, opcode, imm) begin
o_imm = 1'bx;
if (opcode == OP_JAL)
if (cnt > 19) o_imm = imm[31];
else if (cnt > 11) o_imm = imm[cnt];
else if (cnt > 10) o_imm = imm[20];
else if (cnt > 0) o_imm = imm[cnt+20];
else o_imm = 1'b0;
else if ((opcode == OP_OPIMM) | (opcode == OP_JALR))
if (cnt > 10) o_imm = imm[31];
else o_imm = imm[cnt+20];
else if ((opcode == OP_LUI) | (opcode == OP_AUIPC))
if (cnt > 11) o_imm = imm[cnt];
else o_imm = 1'b0;
else if (opcode == OP_LOAD)
if (cnt > 10) o_imm = imm[31];
else o_imm = imm[cnt+20];
else if (opcode == OP_BRANCH)
if (cnt > 11) o_imm = imm[31];
else if (cnt > 10) o_imm = imm[7];
else if (cnt > 4) o_imm = imm[cnt+20];
else if (cnt > 0) o_imm = imm[cnt+7];
else o_imm = 1'b0;
else if (opcode == OP_STORE)
if (cnt > 10) o_imm = imm[31];
else if (cnt > 4) o_imm = imm[cnt+20];
else o_imm = imm[cnt+7];
end
wire imm_j =
(cnt > 19) ? imm[31] :
(cnt > 11) ? imm[cnt] :
(cnt > 10) ? imm[20] :
(cnt > 0) ? imm[cnt+20] :
1'b0;
wire imm_i = (cnt > 10) ? imm[31] : imm[cnt+20];
wire imm_u = (cnt > 11) ? imm[cnt] : 1'b0;
wire imm_b =
(cnt > 11) ? imm[31]:
(cnt > 10) ? imm[7] :
(cnt > 4) ? imm[cnt+20] :
(cnt > 0) ? imm[cnt+7] : 1'b0;
wire imm_s =
(cnt > 10) ? imm[31] :
(cnt > 4) ? imm[cnt+20] :
imm[cnt+7];
wire o_imm =
(opcode == OP_JAL) ? imm_j :
((opcode == OP_OPIMM) | (opcode == OP_JALR) | (opcode == OP_LOAD)) ? imm_i :
((opcode == OP_LUI) | (opcode == OP_AUIPC)) ? imm_u :
(opcode == OP_BRANCH) ? imm_b :
(opcode == OP_STORE) ? imm_s : 1'b0;
always @(posedge clk) begin
go <= i_wb_en;
@@ -340,7 +335,7 @@ module serv_decode
if (cnt_done)
state <= IDLE;
end
default : state <= 2'bxx;
default : state <= IDLE;
endcase
cnt <= cnt + {4'd0,cnt_en};
@@ -350,7 +345,7 @@ module serv_decode
//output reg o_imm,
state <= IDLE;
cnt <= 5'd0;
//reg signbit;
//reg imm30;
//reg [4:0] opcode;
//reg [31:0] imm;
end

View File

@@ -2,6 +2,7 @@
module serv_mem_if
(
input wire i_clk,
input wire i_rst,
input wire i_en,
input wire i_init,
input wire i_dat_valid,
@@ -35,6 +36,7 @@ module serv_mem_if
ser_add ser_add_rs1_plus_imm
(
.clk (i_clk),
.rst (i_rst),
.a (i_rs1),
.b (i_imm),
.clr (!i_en),

View File

@@ -1,9 +1,8 @@
localparam [2:0]
localparam [1:0]
RD_SOURCE_CTRL = 3'd0,
RD_SOURCE_ALU = 3'd1,
RD_SOURCE_IMM = 3'd2,
RD_SOURCE_MEM = 3'd3,
RD_SOURCE_CSR = 3'd4;
RD_SOURCE_MEM = 3'd2,
RD_SOURCE_CSR = 3'd3;
localparam [0:0]
OFFSET_SOURCE_IMM = 1'd0,

View File

@@ -54,7 +54,7 @@ module serv_top
wire [4:0] rs1_addr;
wire [4:0] rs2_addr;
wire [2:0] rd_source;
wire [1:0] rd_source;
wire ctrl_rd;
wire alu_rd;
wire mem_rd;
@@ -68,8 +68,6 @@ module serv_top
wire jalr;
wire auipc;
wire mret;
wire offset;
wire offset_source;
wire imm;
wire trap;
@@ -116,6 +114,8 @@ module serv_top
parameter RESET_PC = 32'd8;
wire lui;
serv_decode decode
(
.clk (clk),
@@ -129,6 +129,7 @@ module serv_top
.o_ctrl_jump (jump),
.o_ctrl_jalr (jalr),
.o_ctrl_auipc (auipc),
.o_ctrl_lui (lui),
.o_ctrl_trap (trap),
.o_ctrl_mret (mret),
.i_ctrl_misalign(ctrl_misalign),
@@ -162,7 +163,6 @@ module serv_top
.o_csr_imm (csr_imm),
.o_csr_d_sel (csr_d_sel),
.o_imm (imm),
.o_offset_source (offset_source),
.o_op_b_source (op_b_source),
.o_rd_source (rd_source));
@@ -176,10 +176,11 @@ module serv_top
.i_pc_en (ctrl_pc_en),
.i_cnt_done (cnt_done),
.i_jump (jump),
.i_offset (offset),
.i_offset (imm),
.i_rs1 (rs1),
.i_jalr (jalr),
.i_auipc (auipc),
.i_lui (lui),
.i_trap (trap | mret),
.i_csr_pc (csr_rd),
.o_rd (ctrl_rd),
@@ -189,23 +190,17 @@ module serv_top
.o_ibus_cyc (o_ibus_cyc),
.i_ibus_ack (i_ibus_ack));
assign offset = (offset_source == OFFSET_SOURCE_IMM) ? imm :
(offset_source == OFFSET_SOURCE_RS1) ? rs1 : 1'bx;
//TODO: Pass imm through alu to avoid 5-way mux
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 :
(rd_source == RD_SOURCE_CSR) ? csr_rd : 1'bx;
(rd_source == RD_SOURCE_MEM) ? mem_rd : csr_rd;
assign op_b = (op_b_source == OP_B_SOURCE_IMM) ? imm :
(op_b_source == OP_B_SOURCE_RS2) ? rs2 :
1'bx;
assign op_b = (op_b_source == OP_B_SOURCE_IMM) ? imm : rs2;
serv_alu alu
(
.clk (clk),
.i_rst (i_rst),
.i_en (alu_en),
.i_rs1 (rs1),
.i_op_b (op_b),
@@ -236,6 +231,7 @@ module serv_top
serv_mem_if mem_if
(
.i_clk (clk),
.i_rst (i_rst),
.i_en (mem_en),
.i_init (mem_init),
.i_dat_valid (mem_dat_valid),

View File

@@ -1,20 +1,11 @@
module wb_gpio
(
input wire i_wb_clk,
input wire i_wb_rst,
input wire i_wb_dat,
input wire i_wb_cyc,
output reg o_wb_ack,
output reg o_gpio = 1'b1);
always @(posedge i_wb_clk) begin
o_wb_ack <= 1'b0;
if (i_wb_cyc) begin
if (!o_wb_ack)
o_wb_ack <= 1'b1;
o_gpio <= i_wb_dat;
end
if (i_wb_rst)
o_wb_ack <= 1'b0;
end
output reg o_gpio);
always @(posedge i_wb_clk)
if (i_wb_cyc)
o_gpio <= i_wb_dat;
endmodule