From b6281221c37a53604c1bb7dc418f7a9f7a579194 Mon Sep 17 00:00:00 2001 From: Raptor Engineering Development Team Date: Sun, 6 Mar 2022 14:36:59 -0600 Subject: [PATCH] Add Pinyon dual port RAM interface --- LICENSE.pinyon | 1 + README.pinyon | 3 ++ pinyon/wishbone_interface.v | 79 +++++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+) create mode 100644 LICENSE.pinyon create mode 100644 README.pinyon create mode 100644 pinyon/wishbone_interface.v diff --git a/LICENSE.pinyon b/LICENSE.pinyon new file mode 100644 index 0000000..b8ecd35 --- /dev/null +++ b/LICENSE.pinyon @@ -0,0 +1 @@ +Pinyon is licensed under the terms of the GPU LGPLv3+ diff --git a/README.pinyon b/README.pinyon new file mode 100644 index 0000000..15fd0c2 --- /dev/null +++ b/README.pinyon @@ -0,0 +1,3 @@ +# ARCHITECTURE + +Pinyon is a Wishbone-compatible lightweight dual-port RAM instance, with modular backend support. diff --git a/pinyon/wishbone_interface.v b/pinyon/wishbone_interface.v new file mode 100644 index 0000000..1eebc67 --- /dev/null +++ b/pinyon/wishbone_interface.v @@ -0,0 +1,79 @@ +// © 2022 Raptor Engineering, LLC +// +// Released under the terms of the LGPL v3+ +// See the LICENSE file for full details +// +// This module provides a standard RAM interface for various FPGA, simulation, and ASIC SRAM blocks +// +// CURRENT BACKENDS +// - Generic (relies on Yosys memory_libmap) +// +// PLANNED BACKENDS +// - 45nm ASIC (cycle-accurate simulation HDL) + +// Default to GENERIC backend +`ifndef PINYON_RAM_BACKEND +`define PINYON_RAM_BACKEND_GENERIC +`define PINYON_RAM_BACKEND GENERIC +`endif + +module pinyon_ram_wishbone( + // Wishbone read port signals + input wire wb_read_port_clk, + input wire [(BLOCK_RAM_ADDR_BUS_WIDTH-1):0] wb_read_port_adr, + output wire [(BLOCK_RAM_DATA_BUS_WIDTH-1):0] wb_read_port_dat_r, + + // Wishbone write port signals + input wire wb_write_port_clk, + input wire wb_write_port_cyc, + input wire wb_write_port_stb, + input wire wb_write_port_we, + input wire [(BLOCK_RAM_ADDR_BUS_WIDTH-1):0] wb_write_port_adr, + input wire [(BLOCK_RAM_DATA_BUS_WIDTH-1):0] wb_write_port_dat_w, + output wire wb_write_port_ack + ); + + // Wishbone port parameters + parameter BLOCK_RAM_ADDR_BUS_WIDTH = 8; + parameter BLOCK_RAM_DATA_BUS_WIDTH = 8; + +`ifdef PINYON_RAM_BACKEND_GENERIC + // Infer appropriate block RAM + reg [(BLOCK_RAM_DATA_BUS_WIDTH-1):0] data_array [((2**BLOCK_RAM_ADDR_BUS_WIDTH)-1):0]; + + integer i; + initial begin + for (i=0; i<((2**BLOCK_RAM_ADDR_BUS_WIDTH)-1); i=i+1) begin + data_array[i] = 0; + end + end + + reg [(BLOCK_RAM_DATA_BUS_WIDTH-1):0] wb_read_port_dat_r_reg = 0; + always @(posedge wb_read_port_clk) begin + wb_read_port_dat_r_reg <= data_array[wb_read_port_adr]; + end + + always @(posedge wb_write_port_clk) begin + if (wb_write_port_cyc && wb_write_port_stb && wb_write_port_we) begin + data_array[wb_write_port_adr] <= wb_write_port_dat_w; + end + end + + // Try not to confuse simple-minded synthesis tooling with the ACK logic + reg wb_write_port_ack_reg = 0; + always @(posedge wb_write_port_clk) begin + if (wb_write_port_cyc && wb_write_port_stb) begin + wb_write_port_ack_reg <= 1; + end else begin + wb_write_port_ack_reg <= 0; + end + end + + // Assign registered outputs + assign wb_read_port_dat_r = wb_read_port_dat_r_reg; + assign wb_write_port_ack = wb_write_port_ack_reg; +`else + `error_invalid_pinyon_backend_requested +`endif + +endmodule \ No newline at end of file -- 2.30.2