File: ../../Sources/context_ram.vhd
0: ----------------------------------------------------------------------------------
1: -- Engineer: Vitor Mendes Camilo
2: ----------------------------------------------------------------------------------
3:
4: library ieee;
5: use ieee.std_logic_1164.all;
6: use ieee.numeric_std.all;
7: use work.openjls_pkg.all;
8:
9: library work;
10: use work.olo_base_pkg_math.all;
11:
12: entity context_ram is
13: generic (
14: RANGE_P : positive := CO_RANGE_STD;
15: RAM_DEPTH : positive := 367;
16: A_WIDTH : positive := CO_AQ_WIDTH_STD;
17: B_WIDTH : positive := CO_BQ_WIDTH_STD;
18: C_WIDTH : positive := CO_CQ_WIDTH;
19: N_WIDTH : positive := CO_NQ_WIDTH_STD;
20: TOTAL_WIDTH : positive := CO_TOTAL_WIDTH_STD
21: );
22: port (
23: iClk : in std_logic;
24: iRst : in std_logic;
25: iWrAddr : in std_logic_vector(log2ceil(RAM_DEPTH) - 1 downto 0);
26: iWrEn : in std_logic;
27: iWrData : in std_logic_vector(TOTAL_WIDTH - 1 downto 0);
28: iRdAddr : in std_logic_vector(log2ceil(RAM_DEPTH) - 1 downto 0);
29: iRdEn : in std_logic;
30: iEndOfImage : in std_logic;
31: oRdData : out std_logic_vector(TOTAL_WIDTH - 1 downto 0)
32: );
33: end entity context_ram;
34:
35: architecture behavioral of context_ram is
36:
37: constant A_INIT : natural := math_max(2, (RANGE_P + 32) / 64);
38: constant B_INIT : integer := 0;
39: constant C_INIT : integer := 0;
40: constant N_INIT : natural := 1;
41:
42: -- Packed init word (A | B | C | N)
43: -- For run context (A | Nn | 0 | N)
44: -- Nn also initializes to 0, like B
45: constant CTX_INIT : std_logic_vector(TOTAL_WIDTH - 1 downto 0) :=
46: std_logic_vector(to_unsigned(A_INIT, A_WIDTH)) &
47: std_logic_vector(to_signed(B_INIT, B_WIDTH)) &
48: std_logic_vector(to_signed(C_INIT, C_WIDTH)) &
49: std_logic_vector(to_unsigned(N_INIT, N_WIDTH));
50:
51: signal sUseInitValue : std_logic_vector(RAM_DEPTH - 1 downto 0); -- Indicates if init value should be used for each address
52: signal sUseInitReg : std_logic; -- Indicates if use init value for the address read last cycle
53: signal sBramRdData : std_logic_vector(TOTAL_WIDTH - 1 downto 0);
54:
55: -- Same-cycle write->read forwarding: rebuilds WBR on top of an RBW BRAM.
56: signal sFwdSameReg : std_logic;
57: signal sWrDataReg : std_logic_vector(TOTAL_WIDTH - 1 downto 0);
58:
59: begin
60:
61: -- Accesses may be in flight on the FIRST reset cycle: the pipeline's valid
62: -- registers clear synchronously, so the pre-reset valid still drives the
63: -- enables that cycle. Harmless by construction — the re-arm wins over the
64: -- read's flag-clear, a write lands in BRAM but stays masked by the re-armed
65: -- init flag, and the read result is consumed by nothing (downstream is
66: -- reset). Verified by directed cases in the module TB.
67:
68: olo_base_ram_sdp_inst : entity work.olo_base_ram_sdp(rtl)
69: generic map (
70: DEPTH_G => RAM_DEPTH,
71: WIDTH_G => TOTAL_WIDTH,
72: ISASYNC_G => false,
73: RDLATENCY_G => 1,
74: RAMSTYLE_G => "auto",
75: RAMBEHAVIOR_G => "RBW",
76: USEBYTEENABLE_G => false,
77: INITSTRING_G => "",
78: INITFORMAT_G => "NONE"
79: )
80: port map (
81: Clk => iClk,
82: Wr_Addr => iWrAddr,
83: Wr_Ena => iWrEn,
84: Wr_Be => open,
85: Wr_Data => iWrData,
86: Rd_Clk => open,
87: Rd_Addr => iRdAddr,
88: Rd_Ena => iRdEn,
89: Rd_Data => sBramRdData
90: );
91:
92: p_init_tracker : process (iClk) is
93: begin
94:
95: if rising_edge(iClk) then
96: if (iRst = '1') then
97: sUseInitValue <= (others => '1');
98: else
99: if (iRdEn = '1') then
100: sUseInitReg <= sUseInitValue(to_integer(unsigned(iRdAddr)));
101: sUseInitValue(to_integer(unsigned(iRdAddr))) <= '0';
102: end if;
103:
104: if (iEndOfImage = '1') then
105: sUseInitValue <= (others => '1');
106: end if;
107: end if;
108: end if;
109:
110: end process p_init_tracker;
111:
112: p_fwd : process (iClk) is
113: begin
114:
115: if rising_edge(iClk) then
116: if (iRst = '1') then
117: sFwdSameReg <= '0';
118: sWrDataReg <= (others => '0');
119: elsif (iRdEn = '1') then
120: sFwdSameReg <= iWrEn and bool2bit(iWrAddr = iRdAddr);
121: sWrDataReg <= iWrData;
122: end if;
123: end if;
124:
125: end process p_fwd;
126:
127: oRdData <= CTX_INIT when sUseInitReg = '1' else
128: sWrDataReg when sFwdSameReg = '1' else
129: sBramRdData;
130:
131: end architecture behavioral;