Accessing BRAM (Xilinx)
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 XEM6310-LX45
module toplevel(
// 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;
reg [3:0] WriteEnByte;
// Circuit behavior
always @ (*) begin
if(regWrite) WriteEnByte = 4'b1111;
else WriteEnByte = 4'b0000;
end
Xilinx_BRAM_Simple_Dual_Port (
.DO(regDataIn),
.DI(regDataOut),
.RDADDR(regAddress[8:0]),
.RDCLK(okClk),
.RDEN(regRead),
.RST(reset),
.WE(WriteEnByte),
.WRADDR(regAddress[8:0]),
.WRCLK(okClk),
.WREN(regWrite)
);
// 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
//XILINX BRAM MACRO
//Generated by Xilinx ISE
module Xilinx_BRAM_Simple_Dual_Port(
input [31:0] DI,
output [31:0 DO,
input [8:0] WRADDR,
input [8:0] RDADDR,
input [3:0] WE,
input WREN,
input RDEN,
input RST,
input SSR,
input WRCLK,
input RDCLK
);
// BRAM_SDP_MACRO: Simple Dual Port RAM
// Spartan-6
// Xilinx HDL Language Template, version 14.7
BRAM_SDP_MACRO #(
.BRAM_SIZE("18Kb"),
.DEVICE("SPARTAN6"),
.WRITE_WIDTH(32),
.READ_WIDTH(32),
.DO_REG(0),
.INIT_FILE ("NONE"),
.SIM_COLLISION_CHECK ("ALL"),
.SRVAL(72'h000000000000000000),
.INIT(72'h000000000000000000),
) BRAM_SDP_MACRO_inst (
.DO(DO),
.DI(DI),
.RDADDR(RDADDR),
.RDCLK(RDCLK),
.RDEN(RDEN),
.REGCE(REGCE),
.RST(RST),
.WE(WE),
.WRADDR(WRADDR),
.WRCLK(WRCLK),
.WREN(WREN) // 1-bit input write port enable
);
// End of BRAM_SDP_MACRO_inst instantiation
endmodule
Code language: Verilog (verilog)
VHDL
-- Configured for XEM6310-LX45
--Circuit signals
signal regAddress : STD_LOGIC_VECTOR(31 downto 0) := x"00000000";
signal regDataOut : STD_LOGIC_VECTOR(31 downto 0);
signal regDataIn : STD_LOGIC_VECTOR(31 downto 0) := x"00000000";
signal regRead : STD_LOGIC;
signal regWrite : STD_LOGIC;
signal writeEn : STD_LOGIC_VECTOR(3 downto 0);
--Circuit behavior
process (regWrite) begin
if(regWrite = '1') then
writeEn <= "1111";
else
writeEn <= "0000";
end if;
end process;
regBridge : okRegisterBridge port map(
okHE=>okHE,
okEH=>okEHx(1*65-1 downto 0*65),
ep_write=>regWrite,
ep_read=>regRead,
ep_address=>regAddress,
ep_dataout=>regDataOut,
ep_datain=>regDataIn
);
-- BRAM_SDP_MACRO: Simple Dual Port RAM
-- Spartan-6
-- Xilinx HDL Language Template, version 14.7
BRAM_SDP_MACRO_inst : BRAM_SDP_MACRO
generic map (
BRAM_SIZE => "18Kb",
DEVICE => "SPARTAN6",
WRITE_WIDTH => 32,
READ_WIDTH => 32,
DO_REG => 0,
INIT_FILE => "NONE",
SIM_COLLISION_CHECK => "ALL"
--Register initialization omitted--
)
port map (
DO => regDataIn,
DI => regDataOut,
RDADDR => regAddress(8 downto 0),
RDCLK => okClk,
RDEN => regRead,
REGCE => '0',
RST => reset,
WE => writeEn
WRADDR => regAddress(8 downto 0),
WRCLK => okClk,
WREN => regWrite
);
Code language: VHDL (vhdl)