File: ../../Sources/A11_2_bit_packer.vhd
0: ----------------------------------------------------------------------------------
1: -- Engineer: Vitor Mendes Camilo
2: --
3: -- Module Name: A11_2_bit_packer - Behavioral
4: -- Description:
5: --
6: -- Concatenates this cycle's raw + Golomb fields into a single
7: -- variable-length word. Output is (oWord, oValidLen): MSB-aligned
8: -- bitstream in oWord, oValidLen counts how many top bits are
9: -- meaningful. Downstream byte_stuffer accumulates these
10: -- variable-length words and produces byte-aligned output.
11: --
12: -- Word layout (MSB → LSB):
13: -- [raw bits (rawLen)][unary zeros (unaryZeros)]['1'][suffix (suffixLen)]
14: --
15: -- When only one of raw/Golomb fires, the corresponding portion is
16: -- omitted. Both fire simultaneously in RI (run-interruption) mode.
17: --
18: -- No internal buffer. Concat is combinational on the inputs;
19: -- outputs are registered to break the comb chain into byte_stuffer.
20: --
21: ----------------------------------------------------------------------------------
22:
23: library ieee;
24: use ieee.std_logic_1164.all;
25: use ieee.numeric_std.all;
26: use work.openjls_pkg.all;
27:
28: library work;
29: use work.olo_base_pkg_math.log2ceil;
30:
31: entity a11_2_bit_packer is
32: generic (
33: LIMIT : natural := CO_LIMIT_STD;
34: UNARY_WIDTH : natural := CO_UNARY_WIDTH_STD;
35: SUFFIX_WIDTH : natural := CO_SUFFIX_WIDTH_STD;
36: SUFFIXLEN_WIDTH : natural := CO_SUFFIXLEN_WIDTH_STD;
37: OUT_WIDTH : natural := CO_LIMIT_STD
38: );
39: port (
40: iClk : in std_logic;
41: iRst : in std_logic;
42: iStall : in std_logic;
43: -- Raw bits interface - A.15 boundary bits, A.16 break residual (Sporadic raws & RI)
44: iRawValid : in std_logic;
45: iRawLen : in unsigned(SUFFIXLEN_WIDTH - 1 downto 0);
46: iRawVal : in unsigned(SUFFIX_WIDTH - 1 downto 0);
47: -- Golomb interface (regular mode & RI)
48: iGolombValid : in std_logic;
49: iUnaryZeros : in unsigned(UNARY_WIDTH - 1 downto 0);
50: iSuffixLen : in unsigned(SUFFIXLEN_WIDTH - 1 downto 0);
51: iSuffixVal : in unsigned(SUFFIX_WIDTH - 1 downto 0);
52: -- Output: MSB-aligned variable-length word
53: oWord : out std_logic_vector(OUT_WIDTH - 1 downto 0);
54: oWordValid : out std_logic;
55: oValidLen : out unsigned(log2ceil(OUT_WIDTH + 1) - 1 downto 0)
56: );
57: end entity a11_2_bit_packer;
58:
59: architecture behavioral of a11_2_bit_packer is
60:
61: signal sCombWord : std_logic_vector(OUT_WIDTH - 1 downto 0);
62: signal sCombValid : std_logic;
63: signal sCombLen : unsigned(log2ceil(OUT_WIDTH + 1) - 1 downto 0);
64:
65: begin
66:
67: assert OUT_WIDTH >= LIMIT
68: report "A11_2_bit_packer: OUT_WIDTH must be >= LIMIT (per-cycle worst case)"
69: severity failure;
70:
71: -- Contract assertions in PSL (active in NVC sims via --psl, plain
72: -- comments to synthesis).
73: -- psl default clock is rising_edge(iClk);
74: -- psl assert always (iRst = '1' -> next (oWordValid = '0')) report "a11_2: reset must clear oWordValid";
75: -- psl assert always ((iRst = '0' and iStall = '1' and oWordValid = '1') -> next (oWordValid = '1')) report "a11_2: stall must hold oWordValid asserted";
76: -- psl assert always ((iRst = '0' and iStall = '1' and oWordValid = '0') -> next (oWordValid = '0')) report "a11_2: stall must hold oWordValid deasserted";
77:
78: -------------------------------------------------------------------------------------------------------------------------
79: -- COMBINATORIAL PROCESS
80: -------------------------------------------------------------------------------------------------------------------------
81: comb_proc : process (iRawValid, iRawLen, iRawVal, iGolombValid, iUnaryZeros, iSuffixLen, iSuffixVal) is
82:
83: constant GOLOMB_WIDTH : natural := LIMIT;
84: variable vWord : unsigned(OUT_WIDTH - 1 downto 0);
85: variable vMarker : unsigned(GOLOMB_WIDTH - 1 downto 0);
86: variable vGolombWord : unsigned(GOLOMB_WIDTH - 1 downto 0);
87: variable vGolombShift : unsigned(OUT_WIDTH - 1 downto 0);
88: variable vRawShift : unsigned(OUT_WIDTH - 1 downto 0);
89: variable vRawLen : natural;
90: variable vSufLen : natural;
91: variable vGolombLen : natural;
92: variable vTotal : natural;
93:
94: begin
95:
96: vWord := (others => '0');
97: vRawLen := to_integer(iRawLen);
98: vSufLen := to_integer(iSuffixLen);
99: vTotal := 0;
100:
101: if (iRawValid = '1' and vRawLen > 0) then
102: vRawShift := shift_left(resize(iRawVal, OUT_WIDTH), OUT_WIDTH - vRawLen);
103: vWord := vRawShift;
104: vTotal := vRawLen;
105: end if;
106:
107: if (iGolombValid = '1') then
108: vMarker := shift_left(to_unsigned(1, GOLOMB_WIDTH), vSufLen);
109: vGolombWord := vMarker or (resize(iSuffixVal, GOLOMB_WIDTH) and (vMarker - 1)); -- Masks the desired suffix bits and adds to marker
110:
111: vGolombLen := to_integer(iUnaryZeros) + 1 + vSufLen;
112: vGolombShift := shift_left(resize(vGolombWord, OUT_WIDTH), OUT_WIDTH - vTotal - vGolombLen);
113:
114: vWord := vWord or vGolombShift;
115: vTotal := vTotal + vGolombLen;
116: end if;
117:
118: sCombWord <= std_logic_vector(vWord);
119: sCombLen <= to_unsigned(vTotal, sCombLen'length);
120: sCombValid <= iRawValid or iGolombValid;
121:
122: end process comb_proc;
123:
124: -------------------------------------------------------------------------------------------------------------------------
125: -- SYNCHRONOUS PROCESS
126: -------------------------------------------------------------------------------------------------------------------------
127: sync_proc : process (iClk) is
128: begin
129:
130: if rising_edge(iClk) then
131: if (iRst = '1') then
132: oWord <= (others => '0');
133: oWordValid <= '0';
134: oValidLen <= (others => '0');
135: elsif (iStall = '0') then
136: oWord <= sCombWord;
137: oWordValid <= sCombValid;
138: oValidLen <= sCombLen;
139: end if;
140: end if;
141:
142: end process sync_proc;
143:
144: end architecture behavioral;