// © 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