From 03d9d7ea8fd3f90d27b7cf20fd2900b374303d47 Mon Sep 17 00:00:00 2001 From: Peter McGoron Date: Sat, 20 Jan 2024 15:23:40 -0500 Subject: [PATCH] add bram --- gateware/rtl/Makefile | 2 ++ gateware/rtl/bram/Makefile | 15 +++++++++ gateware/rtl/bram/bram.v.m4 | 66 +++++++++++++++++++++++++++++++++++++ gateware/soc.py | 6 ++++ 4 files changed, 89 insertions(+) create mode 100644 gateware/rtl/bram/Makefile create mode 100644 gateware/rtl/bram/bram.v.m4 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 ec5537f..19e9216 100644 --- a/gateware/soc.py +++ b/gateware/soc.py @@ -216,6 +216,9 @@ class _CRG(Module): self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_idelay) class UpsilonSoC(SoCCore): + def add_bram(self, region_name): + self.bus.add_region(region_name, SoCRegion(0x2000, cached=False)) + def __init__(self, variant): sys_clk_freq = int(100e6) platform = board_spec.Platform(variant=variant, toolchain="f4pga") @@ -247,6 +250,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) @@ -289,6 +293,8 @@ class UpsilonSoC(SoCCore): pads = platform.request("eth")) self.add_ethernet(phy=self.ethphy, dynamic_ip=True) + self.add_bram("BRAM0") + platform.add_extension(io) self.submodules.base = Base(ClockSignal(), self.sdram, platform)