File: ../../Sources/Xilinx/openjls_axis.vhd
0: -------------------------------------------------------------------------------------------------------------
1: -- Engineer: Vitor Mendes Camilo
2: --
3: -- Module Name: openjls_axis - rtl
4: -- Description: AXI4-Stream wrapper around openjls_top (flavor A).
5: --
6: -- Pure structural adaptation — no state, no clocked logic:
7: --
8: -- * s_axis_pixel : pixel input. One pixel per beat, right-justified in a
9: -- byte-aligned TDATA (16 bits for BITNESS 9..16, 8 bits for
10: -- BITNESS 8). TLAST is accepted and ignored: the core counts
11: -- width x height internally and flags end-of-image itself.
12: --
13: -- * m_axis_jls : encoded .jls byte stream. The core packs the first
14: -- stream byte into the MSB lanes of oData and fills oKeep from
15: -- the top lane down; AXI maps byte lane 0 (TDATA[7:0]) to the
16: -- lowest memory address. The wrapper therefore byte-swaps TDATA
17: -- and remaps oKeep to an LSB-aligned TKEEP so a memory-mapped
18: -- consumer (e.g. AXI DMA S2MM) sees the file byte order.
19: -- Partial beats (TKEEP not all-ones) only occur on the TLAST
20: -- beat, as required by AXI DMA.
21: --
22: -- * iImageWidth/iImageHeight/iRst stay plain ports: the core
23: -- samples the dimensions only while iRst = '1', so whoever owns
24: -- reset owns configuration. See openjls_axis_regs for the
25: -- AXI-Lite flavor that wraps this contract in registers.
26: --
27: -------------------------------------------------------------------------------------------------------------
28:
29: library ieee;
30: use ieee.std_logic_1164.all;
31: use ieee.numeric_std.all;
32: use work.openjls_pkg.all;
33:
34: -- AXI port names must keep the <prefix>_t* suffix convention (lowercase,
35: -- underscores) for Vivado IP integrator interface inference; the prefix
36: -- becomes the interface name in the block diagram.
37: -- vsg_off port_010
38:
39: entity openjls_axis is
40: generic (
41: BITNESS : positive range 8 to 16 := 12;
42: MAX_IMAGE_WIDTH : positive range 4 to 65535 := 4096;
43: MAX_IMAGE_HEIGHT : positive range 1 to 65535 := 4096;
44: OUT_WIDTH : positive range 48 to 1024 := CO_OUT_WIDTH_STD
45: );
46: port (
47: iClk : in std_logic;
48: iRst : in std_logic;
49: iImageWidth : in std_logic_vector(15 downto 0);
50: iImageHeight : in std_logic_vector(15 downto 0);
51: -- AXI4-Stream slave — one pixel per beat, right-justified
52: s_axis_pixel_tdata : in std_logic_vector(8 * ((BITNESS + 7) / 8) - 1 downto 0);
53: s_axis_pixel_tvalid : in std_logic;
54: s_axis_pixel_tlast : in std_logic;
55: s_axis_pixel_tready : out std_logic;
56: -- AXI4-Stream master — encoded .jls byte stream
57: m_axis_jls_tdata : out std_logic_vector(OUT_WIDTH - 1 downto 0);
58: m_axis_jls_tkeep : out std_logic_vector(OUT_WIDTH / 8 - 1 downto 0);
59: m_axis_jls_tvalid : out std_logic;
60: m_axis_jls_tlast : out std_logic;
61: m_axis_jls_tready : in std_logic
62: );
63:
64: -- Vivado IP integrator interface inference
65: attribute x_interface_info : string;
66: attribute x_interface_parameter : string;
67: attribute x_interface_info of iClk : signal is "xilinx.com:signal:clock:1.0 iClk CLK";
68: attribute x_interface_parameter of iClk : signal is "ASSOCIATED_BUSIF s_axis_pixel:m_axis_jls, ASSOCIATED_RESET iRst";
69: attribute x_interface_info of iRst : signal is "xilinx.com:signal:reset:1.0 iRst RST";
70: attribute x_interface_parameter of iRst : signal is "POLARITY ACTIVE_HIGH";
71: end entity openjls_axis;
72:
73: architecture rtl of openjls_axis is
74:
75: signal sCoreData : std_logic_vector(OUT_WIDTH - 1 downto 0);
76: signal sCoreKeep : std_logic_vector(OUT_WIDTH / 8 - 1 downto 0);
77:
78: begin
79:
80: u_openjls_top : entity work.openjls_top(rtl)
81: generic map (
82: BITNESS => BITNESS,
83: MAX_IMAGE_WIDTH => MAX_IMAGE_WIDTH,
84: MAX_IMAGE_HEIGHT => MAX_IMAGE_HEIGHT,
85: OUT_WIDTH => OUT_WIDTH
86: )
87: port map (
88: iClk => iClk,
89: iRst => iRst,
90: iValid => s_axis_pixel_tvalid,
91: iPixel => s_axis_pixel_tdata(BITNESS - 1 downto 0),
92: oReady => s_axis_pixel_tready,
93: iImageWidth => iImageWidth,
94: iImageHeight => iImageHeight,
95: oData => sCoreData,
96: oValid => m_axis_jls_tvalid,
97: oKeep => sCoreKeep,
98: oLast => m_axis_jls_tlast,
99: iReady => m_axis_jls_tready
100: );
101:
102: -- Byte-lane swap: core packs the first stream byte into the MSB lanes;
103: -- AXI byte lane 0 (TDATA[7:0]) goes to the lowest memory address. After the
104: -- swap the valid bytes of a partial (TLAST) beat sit in lanes 0..N-1 with
105: -- an LSB-aligned contiguous TKEEP, as AXI DMA expects.
106:
107: gen_byte_swap : for i in 0 to OUT_WIDTH / 8 - 1 generate
108: m_axis_jls_tdata((i + 1) * 8 - 1 downto i * 8) <= sCoreData(OUT_WIDTH - i * 8 - 1 downto OUT_WIDTH - (i + 1) * 8);
109: m_axis_jls_tkeep(i) <= sCoreKeep(OUT_WIDTH / 8 - 1 - i);
110: end generate gen_byte_swap;
111:
112: end architecture rtl;