From 20cfece6e313754d9ad817933af9cf4102a49c46 Mon Sep 17 00:00:00 2001 From: Joppe Blondel Date: Sun, 22 Feb 2026 20:00:42 +0100 Subject: [PATCH] Added soclet with gpio banks to top --- project.cfg | 86 +++++++------------------------------- rtl/core/soclet.v | 77 ++++++++++++++++++++++++++++++++++ rtl/toplevel/top_generic.v | 44 ++++++++++--------- rtl/toplevel/top_serv.v | 70 ------------------------------- rtl/wb/wb_gpio.v | 5 ++- rtl/wb/wb_gpio_banks.v | 63 ++++++++++++++++++++++++++++ scripts/planahead.sh | 5 ++- scripts/planahead.tcl | 3 +- sim/tb/tb_serving.v | 3 +- sw/blinky/blinky.c | 11 +++-- sw/sweep/Makefile | 56 +++++++++++++++++++++++++ sw/sweep/link.ld | 33 +++++++++++++++ sw/sweep/start.s | 23 ++++++++++ sw/sweep/sweep.c | 14 +++++++ 14 files changed, 321 insertions(+), 172 deletions(-) create mode 100644 rtl/core/soclet.v delete mode 100644 rtl/toplevel/top_serv.v create mode 100644 rtl/wb/wb_gpio_banks.v create mode 100644 sw/sweep/Makefile create mode 100644 sw/sweep/link.ld create mode 100644 sw/sweep/start.s create mode 100644 sw/sweep/sweep.c diff --git a/project.cfg b/project.cfg index 899910b..bd9ec22 100644 --- a/project.cfg +++ b/project.cfg @@ -4,12 +4,6 @@ version = 0.1 out_dir = out build_dir = build -[server] -hostname = localhost -port = 2020 -privkey = /home/joppe/.ssh/id_rsa -pubkey = /home/joppe/.ssh/id_rsa.pub - [target.synth] toolchain = ISE ise_settings = /opt/Xilinx/14.7/ISE_DS/settings64.sh @@ -30,32 +24,7 @@ files_verilog = rtl/util/conv.vh rtl/core/decimate_by_r_q15.v rtl/arch/spartan-6/lvds_comparator.v rtl/arch/spartan-6/clk_gen.v -files_con = boards/mimas_v1/constraints.ucf -files_other = rtl/util/rc_alpha_q15.vh - -[target.ip] -toolchain = ISE_IP -ise_settings = /opt/Xilinx/14.7/ISE_DS/settings64.sh -family = spartan6 -device = xc6slx9 -package = tqg144 -speedgrade = -2 -files_def = boards/mimas_v1/ip/mem_8kx8b.xco - #boards/mimas_v1/ip/clk_gen.xco - -[target.serv] -toolchain = ISE -ise_settings = /opt/Xilinx/14.7/ISE_DS/settings64.sh -family = spartan6 -device = xc6slx9 -package = tqg144 -speedgrade = -2 -toplevel = top_generic -xst_opts = -vlgincdir rtl -files_con = boards/mimas_v1/constraints.ucf -files_other = sw/blinky/blinky.hex - rtl/util/clog2.vh -files_verilog = rtl/serv/serv_aligner.v + rtl/serv/serv_aligner.v rtl/serv/serv_alu.v rtl/serv/serv_bufreg.v rtl/serv/serv_bufreg2.v @@ -79,9 +48,22 @@ files_verilog = rtl/serv/serv_aligner.v rtl/serv/servile.v rtl/serv/serving_ram.v rtl/serv/serving.v - rtl/arch/spartan-6/clk_gen.v rtl/wb/wb_gpio.v - rtl/toplevel/top_serv.v + rtl/wb/wb_gpio_banks.v + rtl/core/soclet.v +files_con = boards/mimas_v1/constraints.ucf +files_other = rtl/util/rc_alpha_q15.vh + rtl/util/clog2.vh + sw/blinky/blinky.hex + +[target.ip] +toolchain = ISE_IP +ise_settings = /opt/Xilinx/14.7/ISE_DS/settings64.sh +family = spartan6 +device = xc6slx9 +package = tqg144 +speedgrade = -2 +files_def = boards/mimas_v1/ip/clk_gen.xco [target.sim] toolchain = iverilog @@ -102,39 +84,3 @@ files_verilog = sim/tb/tb_nco_q15.v sim/overrides/clk_gen.v files_other = rtl/util/conv.vh rtl/util/rc_alpha_q15.vh - -[target.servsim] -toolchain = iverilog -runtime = all -toplevel = tb_serving -ivl_opts = -Irtl/util -files_other = sw/blinky/blinky.hex - rtl/util/clog2.vh -files_verilog = rtl/serv/serv_aligner.v - rtl/serv/serv_alu.v - rtl/serv/serv_bufreg.v - rtl/serv/serv_bufreg2.v - rtl/serv/serv_compdec.v - rtl/serv/serv_csr.v - rtl/serv/serv_ctrl.v - rtl/serv/serv_debug.v - rtl/serv/serv_decode.v - rtl/serv/serv_immdec.v - rtl/serv/serv_mem_if.v - rtl/serv/serv_rf_if.v - rtl/serv/serv_rf_ram_if.v - rtl/serv/serv_rf_ram.v - rtl/serv/serv_rf_top.v - rtl/serv/serv_state.v - rtl/serv/serv_synth_wrapper.v - rtl/serv/serv_top.v - rtl/serv/servile_arbiter.v - rtl/serv/servile_mux.v - rtl/serv/servile_rf_mem_if.v - rtl/serv/servile.v - rtl/serv/serving_ram.v - rtl/serv/serving.v - rtl/arch/spartan-6/clk_gen.v - rtl/wb/wb_gpio.v - rtl/toplevel/top_serv.v - sim/tb/tb_serving.v \ No newline at end of file diff --git a/rtl/core/soclet.v b/rtl/core/soclet.v new file mode 100644 index 0000000..7c1ecc5 --- /dev/null +++ b/rtl/core/soclet.v @@ -0,0 +1,77 @@ +`timescale 1ns/1ps + +module soclet #( + parameter memfile = "", + parameter memsize = 8192, + parameter sim = 1'b0 +)( + input wire i_clk, + input wire i_rst, + + input wire [31:0] i_GPI_A, + input wire [31:0] i_GPI_B, + input wire [31:0] i_GPI_C, + input wire [31:0] i_GPI_D, + + output wire [31:0] o_GPO_A, + output wire [31:0] o_GPO_B, + output wire [31:0] o_GPO_C, + output wire [31:0] o_GPO_D +); + + wire [31:0] wb_adr; + wire [31:0] wb_dat; + wire [31:0] wb_rdt; + wire [3:0] wb_sel; + wire wb_we; + wire wb_stb; + wire wb_ack; + + wire [4*32-1:0] GPO; + wire [4*32-1:0] GPI; + assign o_GPO_A = GPO[32*1-1:32*0]; + assign o_GPO_B = GPO[32*2-1:32*1]; + assign o_GPO_C = GPO[32*3-1:32*2]; + assign o_GPO_D = GPO[32*4-1:32*3]; + assign GPI[32*1-1:32*0] = i_GPI_A; + assign GPI[32*2-1:32*1] = i_GPI_B; + assign GPI[32*3-1:32*2] = i_GPI_C; + assign GPI[32*4-1:32*3] = i_GPI_D; + + serving #( + .memfile(memfile), + .memsize(memsize), + .sim(sim), + .RESET_STRATEGY("MINI"), + .WITH_CSR(1) + ) serv ( + .i_clk(i_clk), + .i_rst(i_rst), + .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_banks #( + .BASE_ADDR(32'h40000000), + .NUM_BANKS(4) + ) gpio ( + .i_wb_clk(i_clk), + .i_wb_rst(i_rst), + .i_wb_dat(wb_dat), + .i_wb_adr(wb_adr), + .i_wb_we(wb_we), + .i_wb_stb(wb_stb), + .i_wb_sel(wb_sel), + .i_gpio(GPI), + .o_wb_rdt(wb_rdt), + .o_wb_ack(wb_ack), + .o_gpio(GPO) + ); + +endmodule \ No newline at end of file diff --git a/rtl/toplevel/top_generic.v b/rtl/toplevel/top_generic.v index 3a576a9..a3eeb3a 100644 --- a/rtl/toplevel/top_generic.v +++ b/rtl/toplevel/top_generic.v @@ -22,38 +22,36 @@ module top_generic( .clk_out_15(clk_15) ); - reg [11:0] count; - localparam integer DIV_MAX = 100_000 - 1; // 1 ms tick at 100 MHz - reg [16:0] div_counter = 0; // enough bits for 100k (2^17=131072) - reg [31:0] freq; - always @(posedge clk_15) begin - if (!aresetn) begin - div_counter <= 0; - count <= 0; - end else begin - if (div_counter == DIV_MAX) begin - div_counter <= 0; - if (count == 12'd3999) - count <= 0; // wrap at 4000 - else - count <= count + 1'b1; // increment every 1 ms - end else begin - div_counter <= div_counter + 1'b1; - end - end - freq <= count; - end + wire [31:0] GPIO_A; + wire [31:0] GPIO_B; + wire [31:0] GPIO_C; + wire [31:0] GPIO_D; + + soclet #( + .memfile("../sw/sweep/sweep.hex") + ) mcu ( + .i_clk(clk_15), + .i_rst(!aresetn), + .i_GPI_A(GPIO_A), + .i_GPI_B(GPIO_B), + .i_GPI_C(GPIO_C), + .i_GPI_D(GPIO_D), + .o_GPO_A(GPIO_A), + .o_GPO_B(GPIO_B), + .o_GPO_C(GPIO_C), + .o_GPO_D(GPIO_D) + ); wire [15:0] sin_q15; wire clk_en; nco_q15 #( .CLK_HZ(15_000_000), - .FS_HZ(40_000) + .FS_HZ(80_000) ) nco ( .clk (clk_15), .rst_n (aresetn), - .freq_hz(freq), + .freq_hz(GPIO_A), .sin_q15(sin_q15), .cos_q15(), .clk_en (clk_en) diff --git a/rtl/toplevel/top_serv.v b/rtl/toplevel/top_serv.v deleted file mode 100644 index 54143ae..0000000 --- a/rtl/toplevel/top_serv.v +++ /dev/null @@ -1,70 +0,0 @@ -`timescale 1ns/1ps - -module top_generic( - input wire aclk, - input wire aresetn, - - output wire led_green, - output wire led_red, - - output wire[5:0] r2r -); - - // Clocking - wire clk_100; - wire clk_15; - assign clk_100 = aclk; - clk_gen clocking( - .clk_in(clk_100), - .clk_out_15(clk_15) - ); - - wire [31:0] wb_adr; - wire [31:0] wb_dat; - wire [31:0] wb_rdt; - wire [3:0] wb_sel; - wire wb_we; - wire wb_stb; - wire wb_ack; - - wire [31:0] GPIO; - - assign led_green = GPIO[0]; - assign led_red = GPIO[1]; - assign r2r = GPIO[8:2]; - - serving #( - .memfile("../sw/blinky/blinky.hex"), - .memsize(8192), - .sim(1'b0), - .RESET_STRATEGY("MINI"), - .WITH_CSR(1) - ) serv ( - .i_clk(clk_15), - .i_rst(!aresetn), - .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 #( - .address(32'h40000000) - ) gpio ( - .i_wb_clk(clk_15), - .i_wb_rst(!aresetn), - .i_wb_dat(wb_dat), - .i_wb_adr(wb_adr), - .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 \ No newline at end of file diff --git a/rtl/wb/wb_gpio.v b/rtl/wb/wb_gpio.v index e8b8f42..da5fcc2 100644 --- a/rtl/wb/wb_gpio.v +++ b/rtl/wb/wb_gpio.v @@ -8,6 +8,7 @@ module wb_gpio #( input wire [3:0] i_wb_sel, input wire i_wb_we, input wire i_wb_stb, + input wire [31:0] i_gpio, output reg [31:0] o_wb_rdt, output reg o_wb_ack, @@ -34,7 +35,7 @@ module wb_gpio #( 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; + o_wb_rdt <= i_gpio; end end @@ -51,4 +52,4 @@ module wb_gpio #( end end -endmodule \ No newline at end of file +endmodule diff --git a/rtl/wb/wb_gpio_banks.v b/rtl/wb/wb_gpio_banks.v new file mode 100644 index 0000000..48f4936 --- /dev/null +++ b/rtl/wb/wb_gpio_banks.v @@ -0,0 +1,63 @@ +`default_nettype none + +module wb_gpio_banks #( + parameter integer NUM_BANKS = 4, + parameter [31:0] BASE_ADDR = 32'h8000_0000 +) ( + input wire i_wb_clk, + input wire i_wb_rst, + 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_stb, + input wire [NUM_BANKS*32-1:0] i_gpio, + output reg [31:0] o_wb_rdt, + output reg o_wb_ack, + output wire [NUM_BANKS*32-1:0] o_gpio +); + + wire [NUM_BANKS-1:0] bank_sel; + wire [NUM_BANKS-1:0] bank_stb; + wire [NUM_BANKS*32-1:0] bank_rdt; + wire [NUM_BANKS-1:0] bank_ack; + + genvar gi; + generate + for (gi = 0; gi < NUM_BANKS; gi = gi + 1) begin : gen_gpio + localparam [31:0] BANK_ADDR = BASE_ADDR + (gi * 4); + + assign bank_sel[gi] = (i_wb_adr == BANK_ADDR); + assign bank_stb[gi] = i_wb_stb & bank_sel[gi]; + + wb_gpio #( + .address(BANK_ADDR) + ) u_gpio ( + .i_wb_clk(i_wb_clk), + .i_wb_rst(i_wb_rst), + .i_wb_adr(i_wb_adr), + .i_wb_dat(i_wb_dat), + .i_wb_sel(i_wb_sel), + .i_wb_we(i_wb_we), + .i_wb_stb(bank_stb[gi]), + .i_gpio(i_gpio[gi*32 +: 32]), + .o_wb_rdt(bank_rdt[gi*32 +: 32]), + .o_wb_ack(bank_ack[gi]), + .o_gpio(o_gpio[gi*32 +: 32]) + ); + end + endgenerate + + integer bi; + always @* begin + o_wb_rdt = 32'h0000_0000; + o_wb_ack = 1'b0; + for (bi = 0; bi < NUM_BANKS; bi = bi + 1) begin + if (bank_sel[bi]) begin + o_wb_rdt = bank_rdt[bi*32 +: 32]; + o_wb_ack = bank_ack[bi]; + end + end + end + +endmodule diff --git a/scripts/planahead.sh b/scripts/planahead.sh index 446dda2..16c4dd4 100755 --- a/scripts/planahead.sh +++ b/scripts/planahead.sh @@ -1,4 +1,5 @@ #!/bin/bash cd build -. /opt/packages/xilinx/ISE/14.7/ISE_DS/settings64.sh -planAhead -mode gui -source ../scripts/planahead.tcl \ No newline at end of file +. /opt/Xilinx/14.7/ISE_DS/settings64.sh +Xephyr :1 -screen 1600x900 & +DISPLAY=:1 planAhead -mode batch -source ../scripts/planahead.tcl \ No newline at end of file diff --git a/scripts/planahead.tcl b/scripts/planahead.tcl index b3c1eff..3d50055 100644 --- a/scripts/planahead.tcl +++ b/scripts/planahead.tcl @@ -4,4 +4,5 @@ add_files -norecurse ../out/synth/synth.ngc import_files -force -norecurse import_files -fileset constrs_1 -force -norecurse ../boards/mimas_v1/constraints.ucf import_as_run -run impl_1 -twx ../out/synth/timing.twx ../out/synth/synth.ncd -open_run impl_1 \ No newline at end of file +open_run impl_1 +start_gui \ No newline at end of file diff --git a/sim/tb/tb_serving.v b/sim/tb/tb_serving.v index f44f6c6..71c4849 100644 --- a/sim/tb/tb_serving.v +++ b/sim/tb/tb_serving.v @@ -58,9 +58,10 @@ module tb_serving(); .i_wb_we(wb_we), .i_wb_stb(wb_stb), .i_wb_sel(wb_sel), + .i_gpio(GPIO), .o_wb_rdt(wb_rdt), .o_wb_ack(wb_ack), .o_gpio(GPIO) ); -endmodule \ No newline at end of file +endmodule diff --git a/sw/blinky/blinky.c b/sw/blinky/blinky.c index fdf9dfe..71a3ae5 100644 --- a/sw/blinky/blinky.c +++ b/sw/blinky/blinky.c @@ -1,8 +1,10 @@ #include #define GPIO_BASE 0x40000000u +#define VOUT_BASE 0x40000004u static volatile uint32_t * const gpio = (volatile uint32_t *)GPIO_BASE; +static volatile uint32_t * const vout = (volatile uint32_t *)VOUT_BASE; static void delay(volatile uint32_t ticks){ while (ticks--) { @@ -15,8 +17,11 @@ int main(void) uint32_t v = 0; for (;;) { - *gpio = v; - v++; - delay(20000u); + for(int i=0; i<1000; i++){ + *vout = v; + v++; + delay(5u); + } + *gpio ^= 0xffffffff; } } diff --git a/sw/sweep/Makefile b/sw/sweep/Makefile new file mode 100644 index 0000000..71e5b85 --- /dev/null +++ b/sw/sweep/Makefile @@ -0,0 +1,56 @@ +TOOLCHAIN_PREFIX ?= riscv64-elf- + +CC := $(TOOLCHAIN_PREFIX)gcc +OBJCOPY := $(TOOLCHAIN_PREFIX)objcopy +OBJDUMP := $(TOOLCHAIN_PREFIX)objdump +SIZE := $(TOOLCHAIN_PREFIX)size + +TARGET := sweep +SRCS_C := sweep.c +SRCS_S := start.s +OBJS := $(SRCS_C:.c=.o) $(SRCS_S:.s=.o) + +ARCH_FLAGS := -march=rv32i_zicsr -mabi=ilp32 +CFLAGS := $(ARCH_FLAGS) -Os -ffreestanding -fno-builtin -Wall -Wextra +ASFLAGS := $(ARCH_FLAGS) +LDFLAGS := $(ARCH_FLAGS) -nostdlib -nostartfiles -Wl,-Bstatic,-Tlink.ld,--gc-sections,-Map,$(TARGET).map + +HEX_TO_COE := ../../scripts/hex_to_coe.py +HEX_TO_MIF := ../../scripts/hex_to_mif.py + +.PHONY: all clean disasm size + +all: $(TARGET).elf $(TARGET).bin $(TARGET).hex $(TARGET).coe $(TARGET).mif $(TARGET).elf.asm + +$(TARGET).elf: $(OBJS) link.ld + $(CC) $(LDFLAGS) -o $@ $(OBJS) + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +%.o: %.s + $(CC) $(ASFLAGS) -c -o $@ $< + +$(TARGET).bin: $(TARGET).elf + $(OBJCOPY) -O binary $< $@ + +$(TARGET).hex: $(TARGET).bin + hexdump -v -e '1/1 "%02x\n"' $< > $@ + +$(TARGET).coe: $(TARGET).hex + $(HEX_TO_COE) $< $@ + +$(TARGET).mif: $(TARGET).hex + $(HEX_TO_MIF) $< $@ + +$(TARGET).elf.asm: $(TARGET).elf + $(OBJDUMP) -d -S $< > $@ + +disasm: $(TARGET).elf.asm + +size: $(TARGET).elf + $(SIZE) $< + +clean: + rm -f $(TARGET).elf $(TARGET).bin $(TARGET).hex $(TARGET).coe $(TARGET).mif \ + $(TARGET).elf.asm $(TARGET).map $(OBJS) diff --git a/sw/sweep/link.ld b/sw/sweep/link.ld new file mode 100644 index 0000000..b14568d --- /dev/null +++ b/sw/sweep/link.ld @@ -0,0 +1,33 @@ +OUTPUT_ARCH("riscv") +ENTRY(_start) + +MEMORY +{ + RAM (rwx) : ORIGIN = 0x00000000, LENGTH = 8K +} + +SECTIONS +{ + .text : + { + KEEP(*(.text.init)) + *(.text .text.*) + *(.rodata .rodata.*) + } > RAM + + .data : + { + *(.data .data.*) + } > RAM + + .bss (NOLOAD) : + { + __bss_start = .; + *(.bss .bss.*) + *(COMMON) + __bss_end = .; + } > RAM + + . = ALIGN(4); + __stack_top = ORIGIN(RAM) + LENGTH(RAM); +} diff --git a/sw/sweep/start.s b/sw/sweep/start.s new file mode 100644 index 0000000..837498e --- /dev/null +++ b/sw/sweep/start.s @@ -0,0 +1,23 @@ +.section .text.init +.globl _start +.type _start, @function + +_start: + la sp, __stack_top + + # Zero .bss + la t0, __bss_start + la t1, __bss_end +1: + bgeu t0, t1, 2f + sw zero, 0(t0) + addi t0, t0, 4 + j 1b + +2: + call main + +3: + j 3b + +.size _start, .-_start diff --git a/sw/sweep/sweep.c b/sw/sweep/sweep.c new file mode 100644 index 0000000..98910c7 --- /dev/null +++ b/sw/sweep/sweep.c @@ -0,0 +1,14 @@ +#include + +#define GPIO_BASE 0x40000000u + +static volatile uint32_t * const R_FREQ = (volatile uint32_t *)GPIO_BASE; + +void main(){ + for(;;){ + for(int i=1000; i<10000; i++){ + *R_FREQ = i; + for(int j=0; j<100; j++) asm volatile("nop"); + } + } +} \ No newline at end of file