Accessing BRAM (Altera)
The okRegisterBridge module is unique among the FrontPanel endpoints in that it does not have an endpoint address. Instead, registers are read and written by referencing a data address, which is the same for both read and write operations. Also unlike other single FrontPanel endpoints, okRegisterBridge interacts with both incoming and outgoing data from the FrontPanel Host interface.
Note that the okRegisterBridge module receives and transmits register addresses and data, but does not store it or find it in memory. It is recommended that you instantiate Block RAM (BRAM) using the primitives provided by Altera and Xilinx in Quartus and the Xilinx ISE to properly access addressable memory. To both write to and read from registers, you will need dual-port RAM.
The example below maps a block RAM used to store filter coefficients to a range of addresses in the Register Bridge.
Verilog
//Configured for the ZEM4310
module setGet(
// Framework I/O here
);
// Framework wire declarations here
wire [31:0] regAddress;
wire [31:0] regDataOut;
reg [31:0] regStore[31:0];
wire [31:0] regDataIn;
wire regRead;
wire regWrite;
wire [1*65-1:0] okEHx;
regDataIn = (regAddress[31:24] == 8’h57) ? firDataOut : 32’h00000000;
firWrite = (regAddress[31:24] == 8’h57) & regWrite;
simple_dual_port_ram_single_clock FIR_Coefficients (
.data(regDataOut[31:0]),
.read_addr(regAddress[4:0]),
.write_addr(regAddress),
.we(firWrite),
.clk(okClk),
.q(firDataOut)
);
// Framework FrontPanel module instantiations here
okRegisterBridge regBridge (
.okHE(okHE),
.okEH(okEHx[0*65 +: 65]),
.ep_write(regWrite),
.ep_read(regRead),
.ep_address(regAddress),
.ep_dataout(regDataOut),
.ep_datain(regDataIn)
);
endmodule
//BRAM Primitive generated by Quartus
// Quartus II Verilog Template
// Simple Dual Port RAM with separate read/write addresses and
// single read/write clock
module simple_dual_port_ram_single_clock
#(parameter DATA_WIDTH=32, parameter ADDR_WIDTH=5)(
input [(DATA_WIDTH-1):0] data,
input [(ADDR_WIDTH-1):0] read_addr, write_addr,
input we, clk,
output reg [(DATA_WIDTH-1):0] q
);
reg [DATA_WIDTH-1:0] ram[2**ADDR_WIDTH-1:0];
always @ (posedge clk)
begin
if (we)
ram[write_addr] <= data;
q <= ram[read_addr];
end
endmodule
Code language: Verilog (verilog)
VHDL
-- Configured for the ZEM4310
--Circuit signals
signal regAddress : natural range 0 to 2**32 - 1;
signal regDataOut : STD_LOGIC_VECTOR(31 downto 0);
signal regDataIn : STD_LOGIC_VECTOR(31 downto 0);
signal regRead : STD_LOGIC;
signal regWrite : STD_LOGIC;
--Component definition goes in architecture portion of VHDL body
component BRAM_primitive
generic
(
DATA_WIDTH : natural := 32;
ADDR_WIDTH : natural := 32
);
port(
clk : in std_logic;
raddr : in natural range 0 to 2**ADDR_WIDTH - 1;
waddr : in natural range 0 to 2**ADDR_WIDTH - 1;
data : in std_logic_vector((DATA_WIDTH-1) downto 0);
we : in std_logic := '1';
q : out std_logic_vector((DATA_WIDTH -1) downto 0)
);
end component;
-- Circuit behavior
--Instantiate BRAM
BRAM_instance : BRAM_primitive port map(
clk => okClk,
raddr => regAddress,
waddr => regAddress,
data => regDataOut,
we => regWrite,
q => regDataIn
);
-- Instantiate the okHost and connect endpoints
okHI : okHost port map (
okUH=>okUH,
okHU=>okHU,
okUHU=>okUHU,
okAA=>okAA,
okClk=>okClk,
okHE=>okHE,
okEH=>okEH
);
okWO : okWireOR generic map (N=>1) port map (okEH=>okEH, okEHx=>okEHx);
regBridge : okRegisterBridge port map (
okHE=>okHE,
okEH=>okEHx(1*65-1 downto 0*65),
ep_write=>regWrite,
ep_address=>regAddress,
ep_dataout=>regDataOut,
ep_datain=>regDataIn
);
Code language: VHDL (vhdl)