diff --git a/gateware/rtl/Makefile b/gateware/rtl/Makefile index 027ec6c..836ed91 100644 --- a/gateware/rtl/Makefile +++ b/gateware/rtl/Makefile @@ -15,6 +15,8 @@ make_control_loop: cd control_loop && make codegen make_waveform: cd waveform && make codegen +make_bram: + cd bram && make bram clean: cd base && make clean cd spi && make clean diff --git a/gateware/rtl/bram/Makefile b/gateware/rtl/bram/Makefile new file mode 100644 index 0000000..1263ca3 --- /dev/null +++ b/gateware/rtl/bram/Makefile @@ -0,0 +1,15 @@ +# Copyright 2024 (C) Peter McGoron +# This file is a part of Upsilon, a free and open source software project. +# For license terms, refer to the files in `doc/copying` in the Upsilon +# source distribution. + +.PHONY: codegen + +all: codegen +####### Codegen ######## + +include ../common.makefile +CODEGEN_FILES=bram.v +codegen: ${CODEGEN_FILES} +clean: + rm -rf obj_dir *.fst ${CODEGEN_FILES} diff --git a/gateware/rtl/bram/bram.v.m4 b/gateware/rtl/bram/bram.v.m4 new file mode 100644 index 0000000..0bb31b9 --- /dev/null +++ b/gateware/rtl/bram/bram.v.m4 @@ -0,0 +1,66 @@ +m4_changequote(`⟨', `⟩') +m4_changecom(⟨/*⟩, ⟨*/⟩) + +/* Copyright 2024 (C) Peter McGoron + * This file is a part of Upsilon, a free and open source software project. + * For license terms, refer to the files in `doc/copying` in the Upsilon + * source distribution. + * + * BRAM to Wishbone interface. + */ +module bram_interface #( + /* This is the last INDEX of the word array, which is indexed in + * words, not octets. */ + parameter [WORD_AMNT_WID-1:0] WORD_AMNT = 2047, + /* Width of the memory bus */ + parameter BUS_WID = 32, + /* Width of a request. */ + parameter WORD_WID = 32, + /* Bitmask used to extract the RAM location in the buffer. */ + parameter ADDR_MASK = 32'h1FFF +) ( + input clk, + + input wb_cyc, + input wb_stb, + input wb_we, + input [4-1:0] wb_sel, + input [BUS_WID-1:0] wb_addr, + input [BUS_WID-1:0] wb_data_i, + output reg wb_ack, + output wb_stall, + output reg [BUS_WID-1:0] wb_data_o, +); + +assign wb_stall = wb_ack; + +reg [BUS_WID-1:0] buffer [WORD_AMNT:0]; + +m4_define(⟨bufwrite⟩, ⟨begin + buffer[mem_addr & ADDR_MASK] <= + (buffer[wb_addr & ADDR_MASK] & $1) + | wb_data_i[$2]; +end⟩) + +always @ (posedge clk) if (wb_cyc && wb_stb && !wb_ack) + if (!wb_we) begin + wb_data_o <= buffer[wb_addr & ADDR_MASK]; + wb_ack <= 1; + end else begin + wb_ack <= 1; + case (wb_sel) + 4'b1111: buffer[wb_addr & ADDR_MASK] <= wb_data_o; + 4'b0001: bufwrite(32'hFFFFFF00, 7:0) + 4'b0010: bufwrite(32'hFFFF00FF, 15:8) + 4'b0011: bufwrite(32'hFFFF0000, 15:0) + 4'b0100: bufwrite(32'hFF00FFFF, 23:16) + 4'b1000: bufwrite(32'h00FFFFFF, 31:24) + 4'b1100: bufwrite(32'h0000FFFF, 31:16) + default: mem_ready <= 1; + endcase + end +else if (!wb_stb) begin + wb_ack <= 0; +end + +endmodule diff --git a/gateware/soc.py b/gateware/soc.py index 37dbf2e..4f000fc 100644 --- a/gateware/soc.py +++ b/gateware/soc.py @@ -219,13 +219,14 @@ class UpsilonSoC(SoCCore): def add_ip(self, ip_str, ip_name): for seg_num, ip_byte in enumerate(ip_str.split('.'),start=1): self.add_constant(f"{ip_name}{seg_num}", int(ip_byte)) + def add_bram(self, region_name): + self.bus.add_region(region_name, SoCRegion(0x2000, cached=False)) def __init__(self, variant="a7-100", local_ip="192.168.2.50", remote_ip="192.168.2.100", tftp_port=6969): - sys_clk_freq = int(100e6) platform = board_spec.Platform(variant=variant, toolchain="f4pga") rst = platform.request("cpu_reset") @@ -257,6 +258,7 @@ class UpsilonSoC(SoCCore): platform.add_source("rtl/control_loop/control_loop.v") # platform.add_source("rtl/waveform/bram_interface_preprocessed.v") # platform.add_source("rtl/waveform/waveform_preprocessed.v") + platform.add_source("rtl/bram/bram_preprocessed.v") platform.add_source("rtl/base/base.v") # SoCCore does not have sane defaults (no integrated rom) @@ -304,6 +306,8 @@ class UpsilonSoC(SoCCore): self.add_ip(remote_ip, "REMOTEIP") self.add_constant("TFTP_SERVER_PORT", tftp_port) + self.add_bram("BRAM0") + # Add pins platform.add_extension(io) self.submodules.base = Base(ClockSignal(), self.sdram, platform)