mirror of
https://github.com/olofk/serv.git
synced 2026-02-26 08:13:40 +00:00
Use custom interconnect. Runs on hw
This commit is contained in:
@@ -27,15 +27,6 @@ Register the serv repo as a core library
|
||||
|
||||
`cd $SERV/workspace && fusesoc library add serv ../serv`
|
||||
|
||||
Override wb_intercon with a custom version
|
||||
|
||||
cd $SERV
|
||||
git clone https://olofk/wb_intercon
|
||||
cd wb_intercon
|
||||
git checkout generator
|
||||
cd $SERV/workspace
|
||||
fusesoc library add wb_intercon ../wb_intercon
|
||||
|
||||
Running test software
|
||||
---------------------
|
||||
|
||||
|
||||
37
bench/serv_arbiter.v
Normal file
37
bench/serv_arbiter.v
Normal file
@@ -0,0 +1,37 @@
|
||||
module serv_arbiter
|
||||
(
|
||||
input i_ibus_active,
|
||||
input [31:0] i_wb_cpu_dbus_adr,
|
||||
input [31:0] i_wb_cpu_dbus_dat,
|
||||
input [3:0] i_wb_cpu_dbus_sel,
|
||||
input i_wb_cpu_dbus_we,
|
||||
input i_wb_cpu_dbus_cyc,
|
||||
output [31:0] o_wb_cpu_dbus_rdt,
|
||||
output o_wb_cpu_dbus_ack,
|
||||
|
||||
input [31:0] i_wb_cpu_ibus_adr,
|
||||
input i_wb_cpu_ibus_cyc,
|
||||
output [31:0] o_wb_cpu_ibus_rdt,
|
||||
output o_wb_cpu_ibus_ack,
|
||||
|
||||
output [31:0] o_wb_cpu_adr,
|
||||
output [31:0] o_wb_cpu_dat,
|
||||
output [3:0] o_wb_cpu_sel,
|
||||
output o_wb_cpu_we,
|
||||
output o_wb_cpu_cyc,
|
||||
input [31:0] i_wb_cpu_rdt,
|
||||
input i_wb_cpu_ack);
|
||||
|
||||
assign o_wb_cpu_dbus_rdt = i_wb_cpu_rdt;
|
||||
assign o_wb_cpu_dbus_ack = i_wb_cpu_ack & !i_ibus_active;
|
||||
|
||||
assign o_wb_cpu_ibus_rdt = i_wb_cpu_rdt;
|
||||
assign o_wb_cpu_ibus_ack = i_wb_cpu_ack & i_ibus_active;
|
||||
|
||||
assign o_wb_cpu_adr = i_ibus_active ? i_wb_cpu_ibus_adr : i_wb_cpu_dbus_adr;
|
||||
assign o_wb_cpu_dat = i_wb_cpu_dbus_dat;
|
||||
assign o_wb_cpu_sel = i_wb_cpu_dbus_sel;
|
||||
assign o_wb_cpu_we = i_wb_cpu_dbus_we & !i_ibus_active;
|
||||
assign o_wb_cpu_cyc = i_ibus_active ? i_wb_cpu_ibus_cyc : i_wb_cpu_dbus_cyc;
|
||||
|
||||
endmodule
|
||||
83
bench/serv_mux.v
Normal file
83
bench/serv_mux.v
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
mem = 00
|
||||
gpio = 01
|
||||
timer = 10
|
||||
testcon = 11
|
||||
*/
|
||||
module serv_mux
|
||||
(
|
||||
input i_clk,
|
||||
input i_rst,
|
||||
input [31:0] i_wb_cpu_adr,
|
||||
input [31:0] i_wb_cpu_dat,
|
||||
input [3:0] i_wb_cpu_sel,
|
||||
input i_wb_cpu_we,
|
||||
input i_wb_cpu_cyc,
|
||||
output [31:0] o_wb_cpu_rdt,
|
||||
output reg o_wb_cpu_ack,
|
||||
|
||||
output [31:0] o_wb_mem_adr,
|
||||
output [31:0] o_wb_mem_dat,
|
||||
output [3:0] o_wb_mem_sel,
|
||||
output o_wb_mem_we,
|
||||
output o_wb_mem_cyc,
|
||||
input [31:0] i_wb_mem_rdt,
|
||||
|
||||
output o_wb_gpio_dat,
|
||||
output o_wb_gpio_cyc,
|
||||
|
||||
output [31:0] o_wb_timer_dat,
|
||||
output o_wb_timer_we,
|
||||
output o_wb_timer_cyc,
|
||||
input [31:0] i_wb_timer_rdt);
|
||||
|
||||
parameter sim = 0;
|
||||
|
||||
wire [1:0] s = i_wb_cpu_adr[31:30];
|
||||
|
||||
assign o_wb_cpu_rdt = s[1] ? i_wb_timer_rdt : i_wb_mem_rdt;
|
||||
always @(posedge i_clk) begin
|
||||
o_wb_cpu_ack <= 1'b0;
|
||||
if (i_wb_cpu_cyc & !o_wb_cpu_ack)
|
||||
o_wb_cpu_ack <= 1'b1;
|
||||
if (i_rst)
|
||||
o_wb_cpu_ack <= 1'b0;
|
||||
end
|
||||
|
||||
assign o_wb_mem_adr = i_wb_cpu_adr;
|
||||
assign o_wb_mem_dat = i_wb_cpu_dat;
|
||||
assign o_wb_mem_sel = i_wb_cpu_sel;
|
||||
assign o_wb_mem_we = i_wb_cpu_we;
|
||||
assign o_wb_mem_cyc = i_wb_cpu_cyc & (s == 2'b00);
|
||||
|
||||
assign o_wb_gpio_dat = i_wb_cpu_dat[0];
|
||||
assign o_wb_gpio_cyc = i_wb_cpu_cyc & (s == 2'b01);
|
||||
|
||||
assign o_wb_timer_dat = i_wb_cpu_dat;
|
||||
assign o_wb_timer_we = i_wb_cpu_we;
|
||||
assign o_wb_timer_cyc = i_wb_cpu_cyc & s[1];
|
||||
|
||||
generate
|
||||
if (sim) begin
|
||||
wire sig_en = (i_wb_cpu_adr[31:28] == 8'h8) & i_wb_cpu_cyc & o_wb_cpu_ack;
|
||||
wire halt_en = (i_wb_cpu_adr[31:28] == 8'h9) & i_wb_cpu_cyc & o_wb_cpu_ack;
|
||||
|
||||
reg [1023:0] signature_file;
|
||||
integer f = 0;
|
||||
|
||||
initial
|
||||
if ($value$plusargs("signature=%s", signature_file)) begin
|
||||
$display("Writing signature to %0s", signature_file);
|
||||
f = $fopen(signature_file, "w");
|
||||
end
|
||||
|
||||
always @(posedge i_clk)
|
||||
if (sig_en & (f != 0))
|
||||
$fwrite(f, "%c", i_wb_cpu_dat[7:0]);
|
||||
else if(halt_en) begin
|
||||
$display("Test complete");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
@@ -4,8 +4,8 @@ module serv_wrapper
|
||||
input wire wb_clk,
|
||||
output wire q);
|
||||
|
||||
// parameter memfile = "hellomin.hex";
|
||||
parameter memfile = "bitbang.hex";
|
||||
parameter memfile = "helloservice4000.hex";
|
||||
// parameter memfile = "bitbang.hex";
|
||||
|
||||
reg [4:0] rst_reg = 5'b11111;
|
||||
|
||||
@@ -16,7 +16,96 @@ module serv_wrapper
|
||||
|
||||
wire timer_irq;
|
||||
|
||||
`include "wb_intercon.vh"
|
||||
wire [31:0] wb_cpu_ibus_adr;
|
||||
wire wb_cpu_ibus_cyc;
|
||||
wire [31:0] wb_cpu_ibus_rdt;
|
||||
wire wb_cpu_ibus_ack;
|
||||
|
||||
wire [31:0] wb_cpu_dbus_adr;
|
||||
wire [31:0] wb_cpu_dbus_dat;
|
||||
wire [3:0] wb_cpu_dbus_sel;
|
||||
wire wb_cpu_dbus_we;
|
||||
wire wb_cpu_dbus_cyc;
|
||||
wire [31:0] wb_cpu_dbus_rdt;
|
||||
wire wb_cpu_dbus_ack;
|
||||
|
||||
wire [31:0] wb_cpu_adr;
|
||||
wire [31:0] wb_cpu_dat;
|
||||
wire [3:0] wb_cpu_sel;
|
||||
wire wb_cpu_we;
|
||||
wire wb_cpu_cyc;
|
||||
wire [31:0] wb_cpu_rdt;
|
||||
wire wb_cpu_ack;
|
||||
|
||||
wire [31:0] wb_mem_adr;
|
||||
wire [31:0] wb_mem_dat;
|
||||
wire [3:0] wb_mem_sel;
|
||||
wire wb_mem_we;
|
||||
wire wb_mem_cyc;
|
||||
wire [31:0] wb_mem_rdt;
|
||||
wire wb_gpio_dat;
|
||||
wire wb_gpio_cyc;
|
||||
wire [31:0] wb_timer_dat;
|
||||
wire wb_timer_we;
|
||||
wire wb_timer_cyc;
|
||||
wire [31:0] wb_timer_rdt;
|
||||
|
||||
serv_arbiter serv_arbiter
|
||||
(
|
||||
.i_ibus_active (wb_cpu_ibus_cyc),
|
||||
.i_wb_cpu_dbus_adr (wb_cpu_dbus_adr),
|
||||
.i_wb_cpu_dbus_dat (wb_cpu_dbus_dat),
|
||||
.i_wb_cpu_dbus_sel (wb_cpu_dbus_sel),
|
||||
.i_wb_cpu_dbus_we (wb_cpu_dbus_we ),
|
||||
.i_wb_cpu_dbus_cyc (wb_cpu_dbus_cyc),
|
||||
.o_wb_cpu_dbus_rdt (wb_cpu_dbus_rdt),
|
||||
.o_wb_cpu_dbus_ack (wb_cpu_dbus_ack),
|
||||
|
||||
.i_wb_cpu_ibus_adr (wb_cpu_ibus_adr),
|
||||
.i_wb_cpu_ibus_cyc (wb_cpu_ibus_cyc),
|
||||
.o_wb_cpu_ibus_rdt (wb_cpu_ibus_rdt),
|
||||
.o_wb_cpu_ibus_ack (wb_cpu_ibus_ack),
|
||||
|
||||
.o_wb_cpu_adr (wb_cpu_adr),
|
||||
.o_wb_cpu_dat (wb_cpu_dat),
|
||||
.o_wb_cpu_sel (wb_cpu_sel),
|
||||
.o_wb_cpu_we (wb_cpu_we ),
|
||||
.o_wb_cpu_cyc (wb_cpu_cyc),
|
||||
.i_wb_cpu_rdt (wb_cpu_rdt),
|
||||
.i_wb_cpu_ack (wb_cpu_ack));
|
||||
|
||||
|
||||
`ifdef VERILATOR
|
||||
parameter sim = 1;
|
||||
`else
|
||||
parameter sim = 0;
|
||||
`endif
|
||||
serv_mux #(sim) serv_mux
|
||||
(
|
||||
.i_clk (wb_clk),
|
||||
.i_rst (wb_rst),
|
||||
.i_wb_cpu_adr (wb_cpu_adr),
|
||||
.i_wb_cpu_dat (wb_cpu_dat),
|
||||
.i_wb_cpu_sel (wb_cpu_sel),
|
||||
.i_wb_cpu_we (wb_cpu_we),
|
||||
.i_wb_cpu_cyc (wb_cpu_cyc),
|
||||
.o_wb_cpu_rdt (wb_cpu_rdt),
|
||||
.o_wb_cpu_ack (wb_cpu_ack),
|
||||
|
||||
.o_wb_mem_adr (wb_mem_adr),
|
||||
.o_wb_mem_dat (wb_mem_dat),
|
||||
.o_wb_mem_sel (wb_mem_sel),
|
||||
.o_wb_mem_we (wb_mem_we),
|
||||
.o_wb_mem_cyc (wb_mem_cyc),
|
||||
.i_wb_mem_rdt (wb_mem_rdt),
|
||||
|
||||
.o_wb_gpio_dat (wb_gpio_dat),
|
||||
.o_wb_gpio_cyc (wb_gpio_cyc),
|
||||
|
||||
.o_wb_timer_dat (wb_timer_dat),
|
||||
.o_wb_timer_we (wb_timer_we),
|
||||
.o_wb_timer_cyc (wb_timer_cyc),
|
||||
.i_wb_timer_rdt (wb_timer_rdt));
|
||||
|
||||
localparam MEMORY_SIZE = 2048*4;
|
||||
|
||||
@@ -41,99 +130,52 @@ module serv_wrapper
|
||||
(// Wishbone interface
|
||||
.wb_clk_i (wb_clk),
|
||||
.wb_rst_i (wb_rst),
|
||||
.wb_adr_i (wb_m2s_mem_adr[$clog2(MEMORY_SIZE)-1:0]),
|
||||
.wb_stb_i (wb_m2s_mem_stb),
|
||||
.wb_cyc_i (wb_m2s_mem_cyc),
|
||||
.wb_cti_i (wb_m2s_mem_cti),
|
||||
.wb_bte_i (wb_m2s_mem_bte),
|
||||
.wb_we_i (wb_m2s_mem_we) ,
|
||||
.wb_sel_i (wb_m2s_mem_sel),
|
||||
.wb_dat_i (wb_m2s_mem_dat),
|
||||
.wb_dat_o (wb_s2m_mem_dat),
|
||||
.wb_ack_o (wb_s2m_mem_ack),
|
||||
.wb_adr_i (wb_mem_adr[$clog2(MEMORY_SIZE)-1:0]),
|
||||
.wb_stb_i (1'b1),
|
||||
.wb_cyc_i (wb_mem_cyc),
|
||||
.wb_cti_i (3'b000),
|
||||
.wb_bte_i (2'b00),
|
||||
.wb_we_i (wb_mem_we) ,
|
||||
.wb_sel_i (wb_mem_sel),
|
||||
.wb_dat_i (wb_mem_dat),
|
||||
.wb_dat_o (wb_mem_rdt),
|
||||
.wb_ack_o (),
|
||||
.wb_err_o ());
|
||||
|
||||
testprint testprint
|
||||
(
|
||||
.i_wb_clk (wb_clk),
|
||||
.i_wb_dat (wb_m2s_testprint_dat),
|
||||
.i_wb_we (wb_m2s_testprint_we),
|
||||
.i_wb_cyc (wb_m2s_testprint_cyc),
|
||||
.i_wb_stb (wb_m2s_testprint_stb),
|
||||
.o_wb_ack (wb_s2m_testprint_ack));
|
||||
|
||||
assign wb_s2m_testprint_dat = 32'h0;
|
||||
|
||||
testhalt testhalt
|
||||
(
|
||||
.i_wb_clk (wb_clk),
|
||||
.i_wb_dat (wb_m2s_testhalt_dat),
|
||||
.i_wb_we (wb_m2s_testhalt_we),
|
||||
.i_wb_cyc (wb_m2s_testhalt_cyc),
|
||||
.i_wb_stb (wb_m2s_testhalt_stb),
|
||||
.o_wb_ack (wb_s2m_testhalt_ack));
|
||||
|
||||
assign wb_s2m_testhalt_dat = 32'h0;
|
||||
|
||||
riscv_timer riscv_timer
|
||||
(.i_clk (wb_clk),
|
||||
.o_irq (timer_irq),
|
||||
.i_wb_adr (wb_m2s_timer_adr),
|
||||
.i_wb_stb (wb_m2s_timer_stb),
|
||||
.i_wb_cyc (wb_m2s_timer_cyc),
|
||||
.i_wb_we (wb_m2s_timer_we) ,
|
||||
.i_wb_sel (wb_m2s_timer_sel),
|
||||
.i_wb_dat (wb_m2s_timer_dat),
|
||||
.o_wb_dat (wb_s2m_timer_dat),
|
||||
.o_wb_ack (wb_s2m_timer_ack));
|
||||
.i_wb_cyc (wb_timer_cyc),
|
||||
.i_wb_we (wb_timer_we) ,
|
||||
.i_wb_dat (wb_timer_dat),
|
||||
.o_wb_dat (wb_timer_rdt));
|
||||
|
||||
wb_gpio gpio
|
||||
(.i_wb_clk (wb_clk),
|
||||
.i_wb_rst (wb_rst),
|
||||
.i_wb_dat (wb_m2s_gpio_dat[0]),
|
||||
.i_wb_cyc (wb_m2s_gpio_cyc),
|
||||
.o_wb_ack (wb_s2m_gpio_ack),
|
||||
.i_wb_dat (wb_gpio_dat),
|
||||
.i_wb_cyc (wb_gpio_cyc),
|
||||
.o_gpio (q));
|
||||
|
||||
reg canary;
|
||||
|
||||
always @(posedge wb_clk)
|
||||
if (wb_rst)
|
||||
canary <= 1'b0;
|
||||
/*else if (wb_m2s_cpu_ibus_cyc &
|
||||
wb_s2m_cpu_ibus_ack &
|
||||
(wb_m2s_cpu_ibus_adr == 32'h00000020))*/
|
||||
else if (wb_m2s_cpu_dbus_cyc & wb_s2m_cpu_dbus_ack)
|
||||
canary <= ~canary;
|
||||
|
||||
// assign q = canary;
|
||||
|
||||
assign wb_s2m_gpio_dat = 32'h0;
|
||||
|
||||
serv_top
|
||||
#(.RESET_PC (32'h0000_0000))
|
||||
cpu
|
||||
(
|
||||
.clk (wb_clk),
|
||||
.i_rst (wb_rst),
|
||||
.o_ibus_adr (wb_m2s_cpu_ibus_adr),
|
||||
.o_ibus_cyc (wb_m2s_cpu_ibus_cyc),
|
||||
.o_ibus_stb (wb_m2s_cpu_ibus_stb),
|
||||
.i_ibus_rdt (wb_s2m_cpu_ibus_dat),
|
||||
.i_ibus_ack (wb_s2m_cpu_ibus_ack),
|
||||
.o_dbus_adr (wb_m2s_cpu_dbus_adr),
|
||||
.o_dbus_dat (wb_m2s_cpu_dbus_dat),
|
||||
.o_dbus_sel (wb_m2s_cpu_dbus_sel),
|
||||
.o_dbus_we (wb_m2s_cpu_dbus_we),
|
||||
.o_dbus_cyc (wb_m2s_cpu_dbus_cyc),
|
||||
.o_dbus_stb (wb_m2s_cpu_dbus_stb),
|
||||
.i_dbus_rdt (wb_s2m_cpu_dbus_dat),
|
||||
.i_dbus_ack (wb_s2m_cpu_dbus_ack));
|
||||
|
||||
assign wb_m2s_cpu_ibus_dat = 32'd0;
|
||||
assign wb_m2s_cpu_ibus_we = 1'b0;
|
||||
assign wb_m2s_cpu_ibus_sel = 4'b1111;
|
||||
assign wb_m2s_cpu_ibus_cti = 3'b000;
|
||||
assign wb_m2s_cpu_ibus_bte = 2'b00;
|
||||
.o_ibus_adr (wb_cpu_ibus_adr),
|
||||
.o_ibus_cyc (wb_cpu_ibus_cyc),
|
||||
.o_ibus_stb (),
|
||||
.i_ibus_rdt (wb_cpu_ibus_rdt),
|
||||
.i_ibus_ack (wb_cpu_ibus_ack),
|
||||
|
||||
.o_dbus_adr (wb_cpu_dbus_adr),
|
||||
.o_dbus_dat (wb_cpu_dbus_dat),
|
||||
.o_dbus_sel (wb_cpu_dbus_sel),
|
||||
.o_dbus_we (wb_cpu_dbus_we),
|
||||
.o_dbus_cyc (wb_cpu_dbus_cyc),
|
||||
.o_dbus_stb (),
|
||||
.i_dbus_rdt (wb_cpu_dbus_rdt),
|
||||
.i_dbus_ack (wb_cpu_dbus_ack));
|
||||
|
||||
endmodule
|
||||
|
||||
16
bitbang.hex
16
bitbang.hex
@@ -1,17 +1,17 @@
|
||||
30000537
|
||||
000073b3
|
||||
00138393
|
||||
41000537
|
||||
7ff50513
|
||||
00018337
|
||||
6a030313
|
||||
00550023
|
||||
7e550fa3
|
||||
41000537
|
||||
7ff50513
|
||||
0012c293
|
||||
000073b3
|
||||
00138393
|
||||
fe731ee3
|
||||
fedff06f
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
fe5ff06f
|
||||
0
|
||||
0
|
||||
0
|
||||
|
||||
2048
helloservice4000.hex
Normal file
2048
helloservice4000.hex
Normal file
File diff suppressed because it is too large
Load Diff
@@ -14,7 +14,7 @@
|
||||
#define RV_COMPLIANCE_HALT \
|
||||
la a0, data_begin; \
|
||||
la a1, data_end; \
|
||||
li a2, 0x10000000; \
|
||||
li a2, 0x80000000; \
|
||||
complience_halt_loop: \
|
||||
beq a0, a1, complience_halt_break; \
|
||||
addi a3, a0, 16; \
|
||||
@@ -47,7 +47,7 @@ notLetter2: \
|
||||
j complience_halt_loop; \
|
||||
j complience_halt_break; \
|
||||
complience_halt_break:; \
|
||||
lui a0,0x20000000>>12; \
|
||||
lui a0,0x90000000>>12; \
|
||||
sw a3,0(a0);
|
||||
|
||||
#define RV_COMPLIANCE_RV32M
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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
|
||||
|
||||
39
serv.core
39
serv.core
@@ -24,6 +24,7 @@ filesets:
|
||||
files:
|
||||
- bitbang.hex : {copyto : bitbang.hex}
|
||||
- hellomin.hex : {copyto : hellomin.hex}
|
||||
- helloservice4000.hex : {copyto : helloservice4000.hex}
|
||||
file_type : user
|
||||
|
||||
pcf:
|
||||
@@ -39,13 +40,13 @@ filesets:
|
||||
depend : ["yosys:techlibs:ice40fork"]
|
||||
wrapper:
|
||||
files:
|
||||
- testhalt.v
|
||||
- testprint.v
|
||||
- rtl/riscv_timer.v
|
||||
- rtl/wb_gpio.v
|
||||
- bench/serv_arbiter.v
|
||||
- bench/serv_mux.v
|
||||
- bench/serv_wrapper.v
|
||||
file_type : verilogSource
|
||||
depend : [wb_intercon, wb_ram]
|
||||
depend : [wb_ram]
|
||||
|
||||
netlist:
|
||||
files: [synth.v : {file_type : verilogSource}]
|
||||
@@ -67,13 +68,11 @@ targets:
|
||||
synth:
|
||||
default_tool : icestorm
|
||||
filesets : [core, mem_files, wrapper, pcf]
|
||||
generate : [wb_intercon]
|
||||
toplevel : serv_wrapper
|
||||
|
||||
tinyfpga_bx:
|
||||
default_tool : icestorm
|
||||
filesets : [core, mem_files, wrapper, tinyfpga_bx]
|
||||
generate : [wb_intercon]
|
||||
tools:
|
||||
icestorm:
|
||||
nextpnr_options : [--lp8k, --package, cm81, --freq, 16]
|
||||
@@ -91,7 +90,6 @@ targets:
|
||||
serv_top_tb:
|
||||
default_tool: icarus
|
||||
filesets : [core, wrapper, serv_top_tb]
|
||||
generate : [wb_intercon]
|
||||
parameters : [RISCV_FORMAL=true, firmware]
|
||||
toplevel : serv_top_tb
|
||||
|
||||
@@ -103,8 +101,7 @@ targets:
|
||||
verilator_tb:
|
||||
default_tool: verilator
|
||||
filesets : [core, wrapper, verilator_tb]
|
||||
generate : [wb_intercon]
|
||||
parameters : [RISCV_FORMAL=true, firmware, signature, uart_baudrate, vcd]
|
||||
parameters : [firmware, signature, uart_baudrate, vcd]
|
||||
tools:
|
||||
verilator:
|
||||
verilator_options : [-Wno-fatal, --trace]
|
||||
@@ -130,29 +127,3 @@ parameters:
|
||||
vcd:
|
||||
datatype : bool
|
||||
paramtype : plusarg
|
||||
|
||||
generate:
|
||||
wb_intercon:
|
||||
generator: wb_intercon_gen
|
||||
parameters:
|
||||
masters:
|
||||
cpu_ibus:
|
||||
slaves : [mem]
|
||||
cpu_dbus:
|
||||
slaves : [mem, testprint, testhalt, gpio, timer]
|
||||
slaves:
|
||||
mem:
|
||||
offset : 0x00000000
|
||||
size : 65536
|
||||
testprint:
|
||||
offset : 0x10000000
|
||||
size : 4
|
||||
testhalt:
|
||||
offset : 0x20000000
|
||||
size : 4
|
||||
gpio:
|
||||
offset : 0x30000000
|
||||
size : 4
|
||||
timer:
|
||||
offset : 0xf00fff40
|
||||
size : 16
|
||||
|
||||
Reference in New Issue
Block a user