Added serv and made a blinky testbench for it

This commit is contained in:
2026-02-21 19:24:18 +01:00
parent 3b04f3a6be
commit a261264fda
12 changed files with 284 additions and 2 deletions

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "external/serv"]
path = external/serv
url = https://github.com/olofk/serv.git

1
external/serv vendored Submodule

Submodule external/serv added at f5ddfaa637

View File

@@ -12,6 +12,7 @@ pubkey = /home/joppe/.ssh/id_rsa.pub
[target.synth] [target.synth]
toolchain = ISE toolchain = ISE
ise_settings = /opt/packages/xilinx/14.7/ISE_DS/settings64.sh
# Toolchain settings # Toolchain settings
family = spartan6 family = spartan6
device = xc6slx9 device = xc6slx9
@@ -34,6 +35,38 @@ files_verilog = rtl/toplevel/top_generic.v
files_con = boards/mimas_v1/constraints.ucf files_con = boards/mimas_v1/constraints.ucf
files_other = rtl/util/conv.vh files_other = rtl/util/conv.vh
[target.serv]
toolchain = iverilog
runtime = all
toplevel = tb_serving
ivl_opts = -Irtl
files_verilog = external/serv/rtl/serv_aligner.v
external/serv/rtl/serv_alu.v
external/serv/rtl/serv_bufreg.v
external/serv/rtl/serv_bufreg2.v
external/serv/rtl/serv_compdec.v
external/serv/rtl/serv_csr.v
external/serv/rtl/serv_ctrl.v
external/serv/rtl/serv_debug.v
external/serv/rtl/serv_decode.v
external/serv/rtl/serv_immdec.v
external/serv/rtl/serv_mem_if.v
external/serv/rtl/serv_rf_if.v
external/serv/rtl/serv_rf_ram_if.v
external/serv/rtl/serv_rf_ram.v
external/serv/rtl/serv_rf_top.v
external/serv/rtl/serv_state.v
external/serv/rtl/serv_synth_wrapper.v
external/serv/rtl/serv_top.v
external/serv/servile/servile_arbiter.v
external/serv/servile/servile_mux.v
external/serv/servile/servile_rf_mem_if.v
external/serv/servile/servile.v
# external/serv/serving/serving_ram.v
sim/overrides/serving_ram.v
external/serv/serving/serving.v
sim/tb/tb_serving.v
[target.sim] [target.sim]
toolchain = iverilog toolchain = iverilog
runtime = all runtime = all

View File

@@ -17,7 +17,7 @@ module sigmadelta_sampler(
); );
reg registered_comp_out; reg registered_comp_out;
always @(posedge clk) registered_comp_out <= o; always @(posedge clk) registered_comp_out <= comp_out;
assign o = registered_comp_out; assign o = registered_comp_out;
endmodule endmodule

View File

@@ -9,7 +9,7 @@ module top_generic(
output wire[5:0] r2r output wire[5:0] r2r
); );
`include "util/conv.vh" `include "../util/conv.vh"
assign led_green = 1'b0; assign led_green = 1'b0;
assign led_red = 1'b0; assign led_red = 1'b0;

View File

@@ -0,0 +1,51 @@
/* serving_ram.v : I/D SRAM for the serving SoC
*
* ISC License
*
* Copyright (C) 2020 Olof Kindgren <olof.kindgren@gmail.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
`default_nettype none
module serving_ram
#(//Memory parameters
parameter depth = 256,
parameter aw = $clog2(depth),
parameter memfile = "")
(input wire i_clk,
input wire [aw-1:0] i_waddr,
input wire [7:0] i_wdata,
input wire i_wen,
input wire [aw-1:0] i_raddr,
output reg [7:0] o_rdata);
reg [7:0] mem [0:depth-1] /* verilator public */;
always @(posedge i_clk) begin
if (i_wen) mem[i_waddr] <= i_wdata;
o_rdata <= mem[i_raddr];
end
integer i;
initial begin
// Fill unused/uninitialized memory with a predefined value
for (i = 0; i < depth; i = i + 1)
mem[i] = 8'h00; // <- pick your fill value (00, FF, etc.)
if (|memfile) begin
$display("Preloading %m from %s", memfile);
$readmemh(memfile, mem);
end
end
endmodule

113
sim/tb/tb_serving.v Normal file
View File

@@ -0,0 +1,113 @@
`timescale 1ns/1ps
module wb_gpio (
input wire i_wb_clk,
input wire i_wb_rst, // optional; tie low if unused
input wire [31:0] i_wb_adr, // optional; can ignore for single-reg
input wire [31:0] i_wb_dat,
input wire [3:0] i_wb_sel,
input wire i_wb_we,
input wire i_wb_stb,
output reg [31:0] o_wb_rdt,
output reg o_wb_ack,
output reg [31:0] o_gpio
);
initial o_gpio <= 32'h00000000;
initial o_wb_rdt <= 32'h00000000;
// One-cycle ACK pulse per request (works even if stb stays high)
always @(posedge i_wb_clk) begin
if (i_wb_rst) begin
o_wb_ack <= 1'b0;
end else begin
o_wb_ack <= i_wb_stb & ~o_wb_ack; // pulse while stb asserted
end
end
// Read data (combinational or registered; registered here)
always @(posedge i_wb_clk) begin
if (i_wb_rst) begin
o_wb_rdt <= 32'h0;
end else if (i_wb_stb && !i_wb_we) begin
o_wb_rdt <= o_gpio;
end
end
// Write latch (update on the acknowledged cycle)
always @(posedge i_wb_clk) begin
if (i_wb_rst) begin
o_gpio <= 32'h0;
end else if (i_wb_stb && i_wb_we && (i_wb_stb & ~o_wb_ack)) begin
// Apply byte enables (so sb works if the master uses sel)
if (i_wb_sel[0]) o_gpio[7:0] <= i_wb_dat[7:0];
if (i_wb_sel[1]) o_gpio[15:8] <= i_wb_dat[15:8];
if (i_wb_sel[2]) o_gpio[23:16] <= i_wb_dat[23:16];
if (i_wb_sel[3]) o_gpio[31:24] <= i_wb_dat[31:24];
end
end
endmodule
module tb_serving();
// Clock and reset generation
reg clk;
reg resetn;
initial clk <= 1'b0;
always #4.17 clk <= !clk;
initial begin
resetn <= 1'b1;
#(4.17*40) resetn <= 1'b0;
#(4.17*40) resetn <= 1'b1;
end;
// Default run
initial begin
$dumpfile("out.vcd");
$dumpvars;
#5_000
$finish;
end;
wire [31:0] wb_adr;
wire [31:0] wb_dat;
wire [3:0] wb_sel;
wire wb_we;
wire wb_stb;
wire [31:0] wb_rdt;
wire wb_ack;
wire [31:0] GPIO;
serving #(
.memfile("../sw/blinky/blinky.hex"),
.memsize(8192),
.sim(1'b0),
.RESET_STRATEGY("MINI"),
.WITH_CSR(1)
) serv (
.i_clk(clk),
.i_rst(!resetn),
.i_timer_irq(1'b0),
.i_wb_rdt(wb_rdt),
.i_wb_ack(wb_ack),
.o_wb_adr(wb_adr),
.o_wb_dat(wb_dat),
.o_wb_sel(wb_sel),
.o_wb_we(wb_we),
.o_wb_stb(wb_stb)
);
wb_gpio gpio (
.i_wb_clk(clk),
.i_wb_dat(wb_dat),
.i_wb_we(wb_we),
.i_wb_stb(wb_stb),
.i_wb_sel(wb_sel),
.o_wb_rdt(wb_rdt),
.o_wb_ack(wb_ack),
.o_gpio(GPIO)
);
endmodule

14
sw/blinky/Makefile Normal file
View File

@@ -0,0 +1,14 @@
TOOLCHAIN_PREFIX?=riscv64-elf-
CC=$(TOOLCHAIN_PREFIX)gcc
OBJCOPY=$(TOOLCHAIN_PREFIX)objcopy
%.elf: %.S link.ld
# $(CC) -nostartfiles -nostdlib -march=rv32i_zicsr -mabi=ilp32 -Tlink.ld -o$@ $<
$(CC) -nostartfiles -nostdlib -ffreestanding -march=rv32i_zicsr -mabi=ilp32 -Tlink.ld -o$@ $<
%.bin: %.elf
$(OBJCOPY) -O binary $< $@
%.hex: %.bin
hexdump -v -e '1/1 "%02x\n"' $< > $@
clean:
rm -f *.elf *.bin *.hex

17
sw/blinky/blinky.S Normal file
View File

@@ -0,0 +1,17 @@
#define GPIO_BASE 0x80000000
#define DELAY 100
.globl _start
_start:
lui a0, %hi(GPIO_BASE)
addi a0, a0, %lo(GPIO_BASE)
addi t0, zero, 0
li t1, DELAY
.lp1:
sb t0, 0(a0)
addi t0, t0, 1
and t2, zero, zero
time1:
addi t2, t2, 1
bne t1, t2, time1
j .lp1

BIN
sw/blinky/blinky.elf Executable file

Binary file not shown.

40
sw/blinky/blinky.hex Normal file
View File

@@ -0,0 +1,40 @@
37
05
00
80
13
05
05
00
93
02
00
00
13
03
40
06
23
00
55
00
93
82
12
00
b3
73
00
00
93
83
13
00
e3
1e
73
fe
6f
f0
df
fe

10
sw/blinky/link.ld Normal file
View File

@@ -0,0 +1,10 @@
OUTPUT_ARCH( "riscv" )
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
.text : { *(.text) }
.data : { *(.data) }
.bss : { *(.bss) }
}