From 6aa6346c0fd768a2f3ff34e61910e75375df0e4b Mon Sep 17 00:00:00 2001 From: Quentin Berthet <quentin.berthet@hesge.ch> Date: Thu, 17 Dec 2020 12:10:47 +0100 Subject: [PATCH] Add headers and fix indentation --- ips/hw/scalp_hl2/src/hdl/scalp_hl2.vhd | 663 +++++++------- .../scalp_hl2/src/hdl/scalp_hl2_S00_AXI.vhd | 831 +++++++++--------- .../scalp_hl2/src/hdl/scalp_hl2_S01_AXI.vhd | 579 ++++++------ ips/hw/scalp_hl2/src/hdl/scalp_hl2_bram.vhd | 163 ++-- ips/hw/scalp_hl2/src/hdl/scalp_hl2_ctrl.vhd | 173 ++-- ips/hw/scalp_hl2/src/hdl/scalp_hl2_pkg.vhd | 93 +- ips/hw/scalp_hl2/src/hdl/scalp_hl2_uart.vhd | 262 +++--- 7 files changed, 1440 insertions(+), 1324 deletions(-) diff --git a/ips/hw/scalp_hl2/src/hdl/scalp_hl2.vhd b/ips/hw/scalp_hl2/src/hdl/scalp_hl2.vhd index ade87d8..578f16c 100644 --- a/ips/hw/scalp_hl2/src/hdl/scalp_hl2.vhd +++ b/ips/hw/scalp_hl2/src/hdl/scalp_hl2.vhd @@ -13,9 +13,10 @@ -- Module Name: scalp_hl2 - arch -- Target Device: hepia-cores.ch:scalp_node:part0:0.1 xc7z015clg485-2 -- Tool version: 2019.2 --- Description: scalp_hl2 +-- Description: SCALP - HEPIALight2 interface IP +-- Work in progress, based on a DMX-512 interface -- --- Last update: 2020/12/17 11:55:23 +-- Last update: 2020/12/17 12:10:09 -- --------------------------------------------------------------------------------- @@ -30,103 +31,103 @@ entity scalp_hl2 is generic ( -- Users to add parameters here - G_PORT_COUNT : integer := 1; - G_CLK_DIV : integer := 200; + G_PORT_COUNT : integer := 1; + G_CLK_DIV : integer := 200; -- User parameters ends -- Do not modify the parameters beyond this line -- Parameters of Axi Slave Bus Interface S00_AXI - C_S00_AXI_DATA_WIDTH : integer := 32; - C_S00_AXI_ADDR_WIDTH : integer := 4; + C_S00_AXI_DATA_WIDTH : integer := 32; + C_S00_AXI_ADDR_WIDTH : integer := 4; -- Parameters of Axi Slave Bus Interface S01_AXI - C_S01_AXI_ID_WIDTH : integer := 1; - C_S01_AXI_DATA_WIDTH : integer := 32; - C_S01_AXI_ADDR_WIDTH : integer := 19; - C_S01_AXI_AWUSER_WIDTH : integer := 0; - C_S01_AXI_ARUSER_WIDTH : integer := 0; - C_S01_AXI_WUSER_WIDTH : integer := 0; - C_S01_AXI_RUSER_WIDTH : integer := 0; - C_S01_AXI_BUSER_WIDTH : integer := 0 + C_S01_AXI_ID_WIDTH : integer := 1; + C_S01_AXI_DATA_WIDTH : integer := 32; + C_S01_AXI_ADDR_WIDTH : integer := 19; + C_S01_AXI_AWUSER_WIDTH : integer := 0; + C_S01_AXI_ARUSER_WIDTH : integer := 0; + C_S01_AXI_WUSER_WIDTH : integer := 0; + C_S01_AXI_RUSER_WIDTH : integer := 0; + C_S01_AXI_BUSER_WIDTH : integer := 0 ); port ( -- Users to add ports here - DMX_OUT : out std_logic_vector(G_PORT_COUNT-1 downto 0); + DMX_OUT : out std_logic_vector(G_PORT_COUNT - 1 downto 0); -- User ports ends -- Do not modify the ports beyond this line - AXI_ACLK : in std_logic; - AXI_ARESETN : in std_logic; + AXI_ACLK : in std_logic; + AXI_ARESETN : in std_logic; -- Ports of Axi Slave Bus Interface S00_AXI - S00_AXI_AWADDR : in std_logic_vector(C_S00_AXI_ADDR_WIDTH-1 downto 0); - S00_AXI_AWPROT : in std_logic_vector(2 downto 0); - S00_AXI_AWVALID : in std_logic; - S00_AXI_AWREADY : out std_logic; - S00_AXI_WDATA : in std_logic_vector(C_S00_AXI_DATA_WIDTH-1 downto 0); - S00_AXI_WSTRB : in std_logic_vector((C_S00_AXI_DATA_WIDTH/8)-1 downto 0); - S00_AXI_WVALID : in std_logic; - S00_AXI_WREADY : out std_logic; - S00_AXI_BRESP : out std_logic_vector(1 downto 0); - S00_AXI_BVALID : out std_logic; - S00_AXI_BREADY : in std_logic; - S00_AXI_ARADDR : in std_logic_vector(C_S00_AXI_ADDR_WIDTH-1 downto 0); - S00_AXI_ARPROT : in std_logic_vector(2 downto 0); - S00_AXI_ARVALID : in std_logic; - S00_AXI_ARREADY : out std_logic; - S00_AXI_RDATA : out std_logic_vector(C_S00_AXI_DATA_WIDTH-1 downto 0); - S00_AXI_RRESP : out std_logic_vector(1 downto 0); - S00_AXI_RVALID : out std_logic; - S00_AXI_RREADY : in std_logic; + S00_AXI_AWADDR : in std_logic_vector(C_S00_AXI_ADDR_WIDTH - 1 downto 0); + S00_AXI_AWPROT : in std_logic_vector(2 downto 0); + S00_AXI_AWVALID : in std_logic; + S00_AXI_AWREADY : out std_logic; + S00_AXI_WDATA : in std_logic_vector(C_S00_AXI_DATA_WIDTH - 1 downto 0); + S00_AXI_WSTRB : in std_logic_vector((C_S00_AXI_DATA_WIDTH/8) - 1 downto 0); + S00_AXI_WVALID : in std_logic; + S00_AXI_WREADY : out std_logic; + S00_AXI_BRESP : out std_logic_vector(1 downto 0); + S00_AXI_BVALID : out std_logic; + S00_AXI_BREADY : in std_logic; + S00_AXI_ARADDR : in std_logic_vector(C_S00_AXI_ADDR_WIDTH - 1 downto 0); + S00_AXI_ARPROT : in std_logic_vector(2 downto 0); + S00_AXI_ARVALID : in std_logic; + S00_AXI_ARREADY : out std_logic; + S00_AXI_RDATA : out std_logic_vector(C_S00_AXI_DATA_WIDTH - 1 downto 0); + S00_AXI_RRESP : out std_logic_vector(1 downto 0); + S00_AXI_RVALID : out std_logic; + S00_AXI_RREADY : in std_logic; -- Ports of Axi Slave Bus Interface S01_AXI - S01_AXI_AWID : in std_logic_vector(C_S01_AXI_ID_WIDTH-1 downto 0); - S01_AXI_AWADDR : in std_logic_vector(C_S01_AXI_ADDR_WIDTH-1 downto 0); - S01_AXI_AWLEN : in std_logic_vector(7 downto 0); - S01_AXI_AWSIZE : in std_logic_vector(2 downto 0); - S01_AXI_AWBURST : in std_logic_vector(1 downto 0); - S01_AXI_AWLOCK : in std_logic; - S01_AXI_AWCACHE : in std_logic_vector(3 downto 0); - S01_AXI_AWPROT : in std_logic_vector(2 downto 0); - S01_AXI_AWQOS : in std_logic_vector(3 downto 0); - S01_AXI_AWREGION : in std_logic_vector(3 downto 0); + S01_AXI_AWID : in std_logic_vector(C_S01_AXI_ID_WIDTH - 1 downto 0); + S01_AXI_AWADDR : in std_logic_vector(C_S01_AXI_ADDR_WIDTH - 1 downto 0); + S01_AXI_AWLEN : in std_logic_vector(7 downto 0); + S01_AXI_AWSIZE : in std_logic_vector(2 downto 0); + S01_AXI_AWBURST : in std_logic_vector(1 downto 0); + S01_AXI_AWLOCK : in std_logic; + S01_AXI_AWCACHE : in std_logic_vector(3 downto 0); + S01_AXI_AWPROT : in std_logic_vector(2 downto 0); + S01_AXI_AWQOS : in std_logic_vector(3 downto 0); + S01_AXI_AWREGION : in std_logic_vector(3 downto 0); --**s01_axi_awuser : in std_logic_vector(C_S01_AXI_AWUSER_WIDTH-1 downto 0); - S01_AXI_AWVALID : in std_logic; - S01_AXI_AWREADY : out std_logic; - S01_AXI_WDATA : in std_logic_vector(C_S01_AXI_DATA_WIDTH-1 downto 0); - S01_AXI_WSTRB : in std_logic_vector((C_S01_AXI_DATA_WIDTH/8)-1 downto 0); - S01_AXI_WLAST : in std_logic; + S01_AXI_AWVALID : in std_logic; + S01_AXI_AWREADY : out std_logic; + S01_AXI_WDATA : in std_logic_vector(C_S01_AXI_DATA_WIDTH - 1 downto 0); + S01_AXI_WSTRB : in std_logic_vector((C_S01_AXI_DATA_WIDTH/8) - 1 downto 0); + S01_AXI_WLAST : in std_logic; --**s01_axi_wuser : in std_logic_vector(C_S01_AXI_WUSER_WIDTH-1 downto 0); - S01_AXI_WVALID : in std_logic; - S01_AXI_WREADY : out std_logic; - S01_AXI_BID : out std_logic_vector(C_S01_AXI_ID_WIDTH-1 downto 0); - S01_AXI_BRESP : out std_logic_vector(1 downto 0); + S01_AXI_WVALID : in std_logic; + S01_AXI_WREADY : out std_logic; + S01_AXI_BID : out std_logic_vector(C_S01_AXI_ID_WIDTH - 1 downto 0); + S01_AXI_BRESP : out std_logic_vector(1 downto 0); --**s01_axi_buser : out std_logic_vector(C_S01_AXI_BUSER_WIDTH-1 downto 0); - S01_AXI_BVALID : out std_logic; - S01_AXI_BREADY : in std_logic; - S01_AXI_ARID : in std_logic_vector(C_S01_AXI_ID_WIDTH-1 downto 0); - S01_AXI_ARADDR : in std_logic_vector(C_S01_AXI_ADDR_WIDTH-1 downto 0); - S01_AXI_ARLEN : in std_logic_vector(7 downto 0); - S01_AXI_ARSIZE : in std_logic_vector(2 downto 0); - S01_AXI_ARBURST : in std_logic_vector(1 downto 0); - S01_AXI_ARLOCK : in std_logic; - S01_AXI_ARCACHE : in std_logic_vector(3 downto 0); - S01_AXI_ARPROT : in std_logic_vector(2 downto 0); - S01_AXI_ARQOS : in std_logic_vector(3 downto 0); - S01_AXI_ARREGION : in std_logic_vector(3 downto 0); + S01_AXI_BVALID : out std_logic; + S01_AXI_BREADY : in std_logic; + S01_AXI_ARID : in std_logic_vector(C_S01_AXI_ID_WIDTH - 1 downto 0); + S01_AXI_ARADDR : in std_logic_vector(C_S01_AXI_ADDR_WIDTH - 1 downto 0); + S01_AXI_ARLEN : in std_logic_vector(7 downto 0); + S01_AXI_ARSIZE : in std_logic_vector(2 downto 0); + S01_AXI_ARBURST : in std_logic_vector(1 downto 0); + S01_AXI_ARLOCK : in std_logic; + S01_AXI_ARCACHE : in std_logic_vector(3 downto 0); + S01_AXI_ARPROT : in std_logic_vector(2 downto 0); + S01_AXI_ARQOS : in std_logic_vector(3 downto 0); + S01_AXI_ARREGION : in std_logic_vector(3 downto 0); --**s01_axi_aruser : in std_logic_vector(C_S01_AXI_ARUSER_WIDTH-1 downto 0); - S01_AXI_ARVALID : in std_logic; - S01_AXI_ARREADY : out std_logic; - S01_AXI_RID : out std_logic_vector(C_S01_AXI_ID_WIDTH-1 downto 0); - S01_AXI_RDATA : out std_logic_vector(C_S01_AXI_DATA_WIDTH-1 downto 0); - S01_AXI_RRESP : out std_logic_vector(1 downto 0); - S01_AXI_RLAST : out std_logic; + S01_AXI_ARVALID : in std_logic; + S01_AXI_ARREADY : out std_logic; + S01_AXI_RID : out std_logic_vector(C_S01_AXI_ID_WIDTH - 1 downto 0); + S01_AXI_RDATA : out std_logic_vector(C_S01_AXI_DATA_WIDTH - 1 downto 0); + S01_AXI_RRESP : out std_logic_vector(1 downto 0); + S01_AXI_RLAST : out std_logic; --**s01_axi_ruser : out std_logic_vector(C_S01_AXI_RUSER_WIDTH-1 downto 0); - S01_AXI_RVALID : out std_logic; - S01_AXI_RREADY : in std_logic + S01_AXI_RVALID : out std_logic; + S01_AXI_RREADY : in std_logic ); end scalp_hl2; @@ -135,173 +136,171 @@ architecture arch of scalp_hl2 is -- component declaration component scalp_hl2_S00_AXI is generic ( - G_PORT_COUNT : integer := 1; - C_S_AXI_DATA_WIDTH : integer := 32; - C_S_AXI_ADDR_WIDTH : integer := 4 + G_PORT_COUNT : integer := 1; + C_S_AXI_DATA_WIDTH : integer := 32; + C_S_AXI_ADDR_WIDTH : integer := 4 ); port ( - ir_mab_clk : out std_logic_vector(C_REG_MAB_CLK_SIZE-1 downto 0); - ir_break_clk : out std_logic_vector(C_REG_BREAK_CLK_SIZE-1 downto 0); - ir_bit_clk : out std_logic_vector(C_REG_BIT_CLK_SIZE-1 downto 0); - ir_chan_count : out std_logic_vector(C_REG_CHAN_COUNT_SIZE-1 downto 0); - ir_global_en : out std_logic_vector(C_REG_GLOBAL_EN_SIZE-1 downto 0); - ir_sof_value : out std_logic_vector((C_REG_SOF_VALUE_SIZE*G_PORT_COUNT)-1 downto 0); - ir_idl_value : out std_logic_vector((C_REG_IDL_SIZE*G_PORT_COUNT)-1 downto 0); - ir_chan_en : out std_logic_vector((C_REG_EN_SIZE*G_PORT_COUNT)-1 downto 0); - - S_AXI_ACLK : in std_logic; - S_AXI_ARESETN : in std_logic; - S_AXI_AWADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0); - S_AXI_AWPROT : in std_logic_vector(2 downto 0); - S_AXI_AWVALID : in std_logic; - S_AXI_AWREADY : out std_logic; - S_AXI_WDATA : in std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); - S_AXI_WSTRB : in std_logic_vector((C_S_AXI_DATA_WIDTH/8)-1 downto 0); - S_AXI_WVALID : in std_logic; - S_AXI_WREADY : out std_logic; - S_AXI_BRESP : out std_logic_vector(1 downto 0); - S_AXI_BVALID : out std_logic; - S_AXI_BREADY : in std_logic; - S_AXI_ARADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0); - S_AXI_ARPROT : in std_logic_vector(2 downto 0); - S_AXI_ARVALID : in std_logic; - S_AXI_ARREADY : out std_logic; - S_AXI_RDATA : out std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); - S_AXI_RRESP : out std_logic_vector(1 downto 0); - S_AXI_RVALID : out std_logic; - S_AXI_RREADY : in std_logic + ir_mab_clk : out std_logic_vector(C_REG_MAB_CLK_SIZE - 1 downto 0); + ir_break_clk : out std_logic_vector(C_REG_BREAK_CLK_SIZE - 1 downto 0); + ir_bit_clk : out std_logic_vector(C_REG_BIT_CLK_SIZE - 1 downto 0); + ir_chan_count : out std_logic_vector(C_REG_CHAN_COUNT_SIZE - 1 downto 0); + ir_global_en : out std_logic_vector(C_REG_GLOBAL_EN_SIZE - 1 downto 0); + ir_sof_value : out std_logic_vector((C_REG_SOF_VALUE_SIZE * G_PORT_COUNT) - 1 downto 0); + ir_idl_value : out std_logic_vector((C_REG_IDL_SIZE * G_PORT_COUNT) - 1 downto 0); + ir_chan_en : out std_logic_vector((C_REG_EN_SIZE * G_PORT_COUNT) - 1 downto 0); + + S_AXI_ACLK : in std_logic; + S_AXI_ARESETN : in std_logic; + S_AXI_AWADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH - 1 downto 0); + S_AXI_AWPROT : in std_logic_vector(2 downto 0); + S_AXI_AWVALID : in std_logic; + S_AXI_AWREADY : out std_logic; + S_AXI_WDATA : in std_logic_vector(C_S_AXI_DATA_WIDTH - 1 downto 0); + S_AXI_WSTRB : in std_logic_vector((C_S_AXI_DATA_WIDTH/8) - 1 downto 0); + S_AXI_WVALID : in std_logic; + S_AXI_WREADY : out std_logic; + S_AXI_BRESP : out std_logic_vector(1 downto 0); + S_AXI_BVALID : out std_logic; + S_AXI_BREADY : in std_logic; + S_AXI_ARADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH - 1 downto 0); + S_AXI_ARPROT : in std_logic_vector(2 downto 0); + S_AXI_ARVALID : in std_logic; + S_AXI_ARREADY : out std_logic; + S_AXI_RDATA : out std_logic_vector(C_S_AXI_DATA_WIDTH - 1 downto 0); + S_AXI_RRESP : out std_logic_vector(1 downto 0); + S_AXI_RVALID : out std_logic; + S_AXI_RREADY : in std_logic ); end component scalp_hl2_S00_AXI; component scalp_hl2_S01_AXI is generic ( - G_PORT_COUNT : integer := 1; - C_S_AXI_ID_WIDTH : integer := 1; - C_S_AXI_DATA_WIDTH : integer := 32; - C_S_AXI_ADDR_WIDTH : integer := 6; - C_S_AXI_AWUSER_WIDTH : integer := 0; - C_S_AXI_ARUSER_WIDTH : integer := 0; - C_S_AXI_WUSER_WIDTH : integer := 0; - C_S_AXI_RUSER_WIDTH : integer := 0; - C_S_AXI_BUSER_WIDTH : integer := 0 + G_PORT_COUNT : integer := 1; + C_S_AXI_ID_WIDTH : integer := 1; + C_S_AXI_DATA_WIDTH : integer := 32; + C_S_AXI_ADDR_WIDTH : integer := 6; + C_S_AXI_AWUSER_WIDTH : integer := 0; + C_S_AXI_ARUSER_WIDTH : integer := 0; + C_S_AXI_WUSER_WIDTH : integer := 0; + C_S_AXI_RUSER_WIDTH : integer := 0; + C_S_AXI_BUSER_WIDTH : integer := 0 ); port ( - i_bram_rdata : in std_logic_vector(31 downto 0); - o_bram_addr : out std_logic_vector(16 downto 0); - o_bram_wdata : out std_logic_vector(31 downto 0); - o_bram_en : out std_logic; - o_bram_we : out std_logic_vector(3 downto 0); - - S_AXI_ACLK : in std_logic; - S_AXI_ARESETN : in std_logic; - S_AXI_AWID : in std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0); - S_AXI_AWADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0); - S_AXI_AWLEN : in std_logic_vector(7 downto 0); - S_AXI_AWSIZE : in std_logic_vector(2 downto 0); - S_AXI_AWBURST : in std_logic_vector(1 downto 0); - S_AXI_AWLOCK : in std_logic; - S_AXI_AWCACHE : in std_logic_vector(3 downto 0); - S_AXI_AWPROT : in std_logic_vector(2 downto 0); - S_AXI_AWQOS : in std_logic_vector(3 downto 0); - S_AXI_AWREGION : in std_logic_vector(3 downto 0); - --**S_AXI_AWUSER : in std_logic_vector(C_S_AXI_AWUSER_WIDTH-1 downto 0); - S_AXI_AWVALID : in std_logic; - S_AXI_AWREADY : out std_logic; - S_AXI_WDATA : in std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); - S_AXI_WSTRB : in std_logic_vector((C_S_AXI_DATA_WIDTH/8)-1 downto 0); - S_AXI_WLAST : in std_logic; - --**S_AXI_WUSER : in std_logic_vector(C_S_AXI_WUSER_WIDTH-1 downto 0); - S_AXI_WVALID : in std_logic; - S_AXI_WREADY : out std_logic; - S_AXI_BID : out std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0); - S_AXI_BRESP : out std_logic_vector(1 downto 0); - --**S_AXI_BUSER : out std_logic_vector(C_S_AXI_BUSER_WIDTH-1 downto 0); - S_AXI_BVALID : out std_logic; - S_AXI_BREADY : in std_logic; - S_AXI_ARID : in std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0); - S_AXI_ARADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0); - S_AXI_ARLEN : in std_logic_vector(7 downto 0); - S_AXI_ARSIZE : in std_logic_vector(2 downto 0); - S_AXI_ARBURST : in std_logic_vector(1 downto 0); - S_AXI_ARLOCK : in std_logic; - S_AXI_ARCACHE : in std_logic_vector(3 downto 0); - S_AXI_ARPROT : in std_logic_vector(2 downto 0); - S_AXI_ARQOS : in std_logic_vector(3 downto 0); - S_AXI_ARREGION : in std_logic_vector(3 downto 0); - --**S_AXI_ARUSER : in std_logic_vector(C_S_AXI_ARUSER_WIDTH-1 downto 0); - S_AXI_ARVALID : in std_logic; - S_AXI_ARREADY : out std_logic; - S_AXI_RID : out std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0); - S_AXI_RDATA : out std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); - S_AXI_RRESP : out std_logic_vector(1 downto 0); - S_AXI_RLAST : out std_logic; - --**S_AXI_RUSER : out std_logic_vector(C_S_AXI_RUSER_WIDTH-1 downto 0); - S_AXI_RVALID : out std_logic; - S_AXI_RREADY : in std_logic + i_bram_rdata : in std_logic_vector(31 downto 0); + o_bram_addr : out std_logic_vector(16 downto 0); + o_bram_wdata : out std_logic_vector(31 downto 0); + o_bram_en : out std_logic; + o_bram_we : out std_logic_vector(3 downto 0); + + S_AXI_ACLK : in std_logic; + S_AXI_ARESETN : in std_logic; + S_AXI_AWID : in std_logic_vector(C_S_AXI_ID_WIDTH - 1 downto 0); + S_AXI_AWADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH - 1 downto 0); + S_AXI_AWLEN : in std_logic_vector(7 downto 0); + S_AXI_AWSIZE : in std_logic_vector(2 downto 0); + S_AXI_AWBURST : in std_logic_vector(1 downto 0); + S_AXI_AWLOCK : in std_logic; + S_AXI_AWCACHE : in std_logic_vector(3 downto 0); + S_AXI_AWPROT : in std_logic_vector(2 downto 0); + S_AXI_AWQOS : in std_logic_vector(3 downto 0); + S_AXI_AWREGION : in std_logic_vector(3 downto 0); + --**S_AXI_AWUSER : in std_logic_vector(C_S_AXI_AWUSER_WIDTH-1 downto 0); + S_AXI_AWVALID : in std_logic; + S_AXI_AWREADY : out std_logic; + S_AXI_WDATA : in std_logic_vector(C_S_AXI_DATA_WIDTH - 1 downto 0); + S_AXI_WSTRB : in std_logic_vector((C_S_AXI_DATA_WIDTH/8) - 1 downto 0); + S_AXI_WLAST : in std_logic; + --**S_AXI_WUSER : in std_logic_vector(C_S_AXI_WUSER_WIDTH-1 downto 0); + S_AXI_WVALID : in std_logic; + S_AXI_WREADY : out std_logic; + S_AXI_BID : out std_logic_vector(C_S_AXI_ID_WIDTH - 1 downto 0); + S_AXI_BRESP : out std_logic_vector(1 downto 0); + --**S_AXI_BUSER : out std_logic_vector(C_S_AXI_BUSER_WIDTH-1 downto 0); + S_AXI_BVALID : out std_logic; + S_AXI_BREADY : in std_logic; + S_AXI_ARID : in std_logic_vector(C_S_AXI_ID_WIDTH - 1 downto 0); + S_AXI_ARADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH - 1 downto 0); + S_AXI_ARLEN : in std_logic_vector(7 downto 0); + S_AXI_ARSIZE : in std_logic_vector(2 downto 0); + S_AXI_ARBURST : in std_logic_vector(1 downto 0); + S_AXI_ARLOCK : in std_logic; + S_AXI_ARCACHE : in std_logic_vector(3 downto 0); + S_AXI_ARPROT : in std_logic_vector(2 downto 0); + S_AXI_ARQOS : in std_logic_vector(3 downto 0); + S_AXI_ARREGION : in std_logic_vector(3 downto 0); + --**S_AXI_ARUSER : in std_logic_vector(C_S_AXI_ARUSER_WIDTH-1 downto 0); + S_AXI_ARVALID : in std_logic; + S_AXI_ARREADY : out std_logic; + S_AXI_RID : out std_logic_vector(C_S_AXI_ID_WIDTH - 1 downto 0); + S_AXI_RDATA : out std_logic_vector(C_S_AXI_DATA_WIDTH - 1 downto 0); + S_AXI_RRESP : out std_logic_vector(1 downto 0); + S_AXI_RLAST : out std_logic; + --**S_AXI_RUSER : out std_logic_vector(C_S_AXI_RUSER_WIDTH-1 downto 0); + S_AXI_RVALID : out std_logic; + S_AXI_RREADY : in std_logic ); end component scalp_hl2_S01_AXI; - - component scalp_hl2_ctrl is - generic ( - G_PORT_COUNT : integer - ); - port ( - i_clk : in std_logic; - i_nrst : in std_logic; - - -- Config registers - ir_mab_clk : in std_logic_vector(C_REG_MAB_CLK_SIZE-1 downto 0); - ir_break_clk : in std_logic_vector(C_REG_BREAK_CLK_SIZE-1 downto 0); - ir_bit_clk : in std_logic_vector(C_REG_BIT_CLK_SIZE-1 downto 0); - ir_chan_count : in std_logic_vector(C_REG_CHAN_COUNT_SIZE-1 downto 0); - ir_global_en : in std_logic_vector(C_REG_GLOBAL_EN_SIZE-1 downto 0); - ir_sof_value : in std_logic_vector((C_REG_SOF_VALUE_SIZE*G_PORT_COUNT)-1 downto 0); - ir_idl_value : in std_logic_vector((C_REG_IDL_SIZE*G_PORT_COUNT)-1 downto 0); - ir_chan_en : in std_logic_vector((C_REG_EN_SIZE*G_PORT_COUNT)-1 downto 0); - - -- Data bus - i_data : in std_logic_vector((8*G_PORT_COUNT)-1 downto 0); - o_addr : out std_logic_vector(C_REG_CHAN_COUNT_SIZE-1 downto 0); - o_rden : out std_logic; - - -- Dmx - o_dmx : out std_logic_vector(G_PORT_COUNT-1 downto 0) - ); + generic ( + G_PORT_COUNT : integer + ); + port ( + i_clk : in std_logic; + i_nrst : in std_logic; + + -- Config registers + ir_mab_clk : in std_logic_vector(C_REG_MAB_CLK_SIZE - 1 downto 0); + ir_break_clk : in std_logic_vector(C_REG_BREAK_CLK_SIZE - 1 downto 0); + ir_bit_clk : in std_logic_vector(C_REG_BIT_CLK_SIZE - 1 downto 0); + ir_chan_count : in std_logic_vector(C_REG_CHAN_COUNT_SIZE - 1 downto 0); + ir_global_en : in std_logic_vector(C_REG_GLOBAL_EN_SIZE - 1 downto 0); + ir_sof_value : in std_logic_vector((C_REG_SOF_VALUE_SIZE * G_PORT_COUNT) - 1 downto 0); + ir_idl_value : in std_logic_vector((C_REG_IDL_SIZE * G_PORT_COUNT) - 1 downto 0); + ir_chan_en : in std_logic_vector((C_REG_EN_SIZE * G_PORT_COUNT) - 1 downto 0); + + -- Data bus + i_data : in std_logic_vector((8 * G_PORT_COUNT) - 1 downto 0); + o_addr : out std_logic_vector(C_REG_CHAN_COUNT_SIZE - 1 downto 0); + o_rden : out std_logic; + + -- Dmx + o_dmx : out std_logic_vector(G_PORT_COUNT - 1 downto 0) + ); end component scalp_hl2_ctrl; component scalp_hl2_bram is - generic ( - G_PORT_COUNT : integer - ); - port ( - i_clk : in std_logic; - i_nrst : in std_logic; - - -- AXI Ports Data bus - o_axi_data : out std_logic_vector(31 downto 0); - i_axi_addr : in std_logic_vector(16 downto 0); - i_axi_data : in std_logic_vector(31 downto 0); - i_axi_en : in std_logic; - i_axi_we : in std_logic_vector(3 downto 0); - - -- DMX Ports Data bus - o_dmx_data : out std_logic_vector((8*G_PORT_COUNT)-1 downto 0); - i_dmx_addr : in std_logic_vector(C_REG_CHAN_COUNT_SIZE-1 downto 0); - i_dmx_rden : in std_logic - ); + generic ( + G_PORT_COUNT : integer + ); + port ( + i_clk : in std_logic; + i_nrst : in std_logic; + + -- AXI Ports Data bus + o_axi_data : out std_logic_vector(31 downto 0); + i_axi_addr : in std_logic_vector(16 downto 0); + i_axi_data : in std_logic_vector(31 downto 0); + i_axi_en : in std_logic; + i_axi_we : in std_logic_vector(3 downto 0); + + -- DMX Ports Data bus + o_dmx_data : out std_logic_vector((8 * G_PORT_COUNT) - 1 downto 0); + i_dmx_addr : in std_logic_vector(C_REG_CHAN_COUNT_SIZE - 1 downto 0); + i_dmx_rden : in std_logic + ); end component; -- AXI4-lite -> DMX ctrl interface (control registers) - signal s_mab_clk : std_logic_vector(C_REG_MAB_CLK_SIZE-1 downto 0); - signal s_break_clk : std_logic_vector(C_REG_BREAK_CLK_SIZE-1 downto 0); - signal s_bit_clk : std_logic_vector(C_REG_BIT_CLK_SIZE-1 downto 0); - signal s_chan_count: std_logic_vector(C_REG_CHAN_COUNT_SIZE-1 downto 0); - signal s_global_en : std_logic_vector(C_REG_GLOBAL_EN_SIZE-1 downto 0); - signal s_sof_value : std_logic_vector((C_REG_SOF_VALUE_SIZE*G_PORT_COUNT)-1 downto 0); - signal s_idl_value : std_logic_vector((C_REG_IDL_SIZE*G_PORT_COUNT)-1 downto 0); - signal s_chan_en : std_logic_vector((C_REG_EN_SIZE*G_PORT_COUNT)-1 downto 0); + signal s_mab_clk : std_logic_vector(C_REG_MAB_CLK_SIZE - 1 downto 0); + signal s_break_clk : std_logic_vector(C_REG_BREAK_CLK_SIZE - 1 downto 0); + signal s_bit_clk : std_logic_vector(C_REG_BIT_CLK_SIZE - 1 downto 0); + signal s_chan_count : std_logic_vector(C_REG_CHAN_COUNT_SIZE - 1 downto 0); + signal s_global_en : std_logic_vector(C_REG_GLOBAL_EN_SIZE - 1 downto 0); + signal s_sof_value : std_logic_vector((C_REG_SOF_VALUE_SIZE * G_PORT_COUNT) - 1 downto 0); + signal s_idl_value : std_logic_vector((C_REG_IDL_SIZE * G_PORT_COUNT) - 1 downto 0); + signal s_chan_en : std_logic_vector((C_REG_EN_SIZE * G_PORT_COUNT) - 1 downto 0); -- AXI4-full <-> BRAM signal s_axi_bram_rdata : std_logic_vector(31 downto 0); @@ -311,73 +310,73 @@ architecture arch of scalp_hl2 is signal s_axi_bram_we : std_logic_vector(3 downto 0); -- BRAM -> DMX ctrl interface - signal s_dmx_data : std_logic_vector((8*G_PORT_COUNT)-1 downto 0); - signal s_dmx_addr : std_logic_vector(C_REG_CHAN_COUNT_SIZE-1 downto 0); - signal s_dmx_rden : std_logic; + signal s_dmx_data : std_logic_vector((8 * G_PORT_COUNT) - 1 downto 0); + signal s_dmx_addr : std_logic_vector(C_REG_CHAN_COUNT_SIZE - 1 downto 0); + signal s_dmx_rden : std_logic; begin --- Instantiation of Axi Bus Interface S00_AXI -scalp_hl2_S00_AXI_inst : scalp_hl2_S00_AXI - generic map ( - G_PORT_COUNT => G_PORT_COUNT, - C_S_AXI_DATA_WIDTH => C_S00_AXI_DATA_WIDTH, - C_S_AXI_ADDR_WIDTH => C_S00_AXI_ADDR_WIDTH + -- Instantiation of Axi Bus Interface S00_AXI + scalp_hl2_S00_AXI_inst : scalp_hl2_S00_AXI + generic map( + G_PORT_COUNT => G_PORT_COUNT, + C_S_AXI_DATA_WIDTH => C_S00_AXI_DATA_WIDTH, + C_S_AXI_ADDR_WIDTH => C_S00_AXI_ADDR_WIDTH ) - port map ( + port map( -- Config registers - ir_mab_clk => s_mab_clk, - ir_break_clk => s_break_clk, - ir_bit_clk => s_bit_clk, - ir_chan_count => s_chan_count, - ir_global_en => s_global_en, - ir_sof_value => s_sof_value, - ir_idl_value => s_idl_value, - ir_chan_en => s_chan_en, - - S_AXI_ACLK => AXI_ACLK, - S_AXI_ARESETN => AXI_ARESETN, - S_AXI_AWADDR => S00_AXI_AWADDR, - S_AXI_AWPROT => S00_AXI_AWPROT, - S_AXI_AWVALID => S00_AXI_AWVALID, - S_AXI_AWREADY => S00_AXI_AWREADY, - S_AXI_WDATA => S00_AXI_WDATA, - S_AXI_WSTRB => S00_AXI_WSTRB, - S_AXI_WVALID => S00_AXI_WVALID, - S_AXI_WREADY => S00_AXI_WREADY, - S_AXI_BRESP => S00_AXI_BRESP, - S_AXI_BVALID => S00_AXI_BVALID, - S_AXI_BREADY => S00_AXI_BREADY, - S_AXI_ARADDR => S00_AXI_ARADDR, - S_AXI_ARPROT => S00_AXI_ARPROT, - S_AXI_ARVALID => S00_AXI_ARVALID, - S_AXI_ARREADY => S00_AXI_ARREADY, - S_AXI_RDATA => S00_AXI_RDATA, - S_AXI_RRESP => S00_AXI_RRESP, - S_AXI_RVALID => S00_AXI_RVALID, - S_AXI_RREADY => S00_AXI_RREADY + ir_mab_clk => s_mab_clk, + ir_break_clk => s_break_clk, + ir_bit_clk => s_bit_clk, + ir_chan_count => s_chan_count, + ir_global_en => s_global_en, + ir_sof_value => s_sof_value, + ir_idl_value => s_idl_value, + ir_chan_en => s_chan_en, + + S_AXI_ACLK => AXI_ACLK, + S_AXI_ARESETN => AXI_ARESETN, + S_AXI_AWADDR => S00_AXI_AWADDR, + S_AXI_AWPROT => S00_AXI_AWPROT, + S_AXI_AWVALID => S00_AXI_AWVALID, + S_AXI_AWREADY => S00_AXI_AWREADY, + S_AXI_WDATA => S00_AXI_WDATA, + S_AXI_WSTRB => S00_AXI_WSTRB, + S_AXI_WVALID => S00_AXI_WVALID, + S_AXI_WREADY => S00_AXI_WREADY, + S_AXI_BRESP => S00_AXI_BRESP, + S_AXI_BVALID => S00_AXI_BVALID, + S_AXI_BREADY => S00_AXI_BREADY, + S_AXI_ARADDR => S00_AXI_ARADDR, + S_AXI_ARPROT => S00_AXI_ARPROT, + S_AXI_ARVALID => S00_AXI_ARVALID, + S_AXI_ARREADY => S00_AXI_ARREADY, + S_AXI_RDATA => S00_AXI_RDATA, + S_AXI_RRESP => S00_AXI_RRESP, + S_AXI_RVALID => S00_AXI_RVALID, + S_AXI_RREADY => S00_AXI_RREADY ); --- Instantiation of Axi Bus Interface S01_AXI -scalp_hl2_S01_AXI_inst : scalp_hl2_S01_AXI - generic map ( - G_PORT_COUNT => G_PORT_COUNT, - C_S_AXI_ID_WIDTH => C_S01_AXI_ID_WIDTH, - C_S_AXI_DATA_WIDTH => C_S01_AXI_DATA_WIDTH, - C_S_AXI_ADDR_WIDTH => C_S01_AXI_ADDR_WIDTH, - C_S_AXI_AWUSER_WIDTH => C_S01_AXI_AWUSER_WIDTH, - C_S_AXI_ARUSER_WIDTH => C_S01_AXI_ARUSER_WIDTH, - C_S_AXI_WUSER_WIDTH => C_S01_AXI_WUSER_WIDTH, - C_S_AXI_RUSER_WIDTH => C_S01_AXI_RUSER_WIDTH, - C_S_AXI_BUSER_WIDTH => C_S01_AXI_BUSER_WIDTH + -- Instantiation of Axi Bus Interface S01_AXI + scalp_hl2_S01_AXI_inst : scalp_hl2_S01_AXI + generic map( + G_PORT_COUNT => G_PORT_COUNT, + C_S_AXI_ID_WIDTH => C_S01_AXI_ID_WIDTH, + C_S_AXI_DATA_WIDTH => C_S01_AXI_DATA_WIDTH, + C_S_AXI_ADDR_WIDTH => C_S01_AXI_ADDR_WIDTH, + C_S_AXI_AWUSER_WIDTH => C_S01_AXI_AWUSER_WIDTH, + C_S_AXI_ARUSER_WIDTH => C_S01_AXI_ARUSER_WIDTH, + C_S_AXI_WUSER_WIDTH => C_S01_AXI_WUSER_WIDTH, + C_S_AXI_RUSER_WIDTH => C_S01_AXI_RUSER_WIDTH, + C_S_AXI_BUSER_WIDTH => C_S01_AXI_BUSER_WIDTH ) - port map ( + port map( - i_bram_rdata => s_axi_bram_rdata, - o_bram_addr => s_axi_bram_addr, - o_bram_wdata => s_axi_bram_wdata, - o_bram_en => s_axi_bram_en, - o_bram_we => s_axi_bram_we, + i_bram_rdata => s_axi_bram_rdata, + o_bram_addr => s_axi_bram_addr, + o_bram_wdata => s_axi_bram_wdata, + o_bram_en => s_axi_bram_en, + o_bram_we => s_axi_bram_we, S_AXI_ACLK => AXI_ACLK, S_AXI_ARESETN => AXI_ARESETN, @@ -392,16 +391,16 @@ scalp_hl2_S01_AXI_inst : scalp_hl2_S01_AXI S_AXI_AWQOS => S01_AXI_AWQOS, S_AXI_AWREGION => S01_AXI_AWREGION, --**S_AXI_AWUSER => S01_AXI_AWUSER, - S_AXI_AWVALID => S01_AXI_AWVALID, - S_AXI_AWREADY => S01_AXI_AWREADY, - S_AXI_WDATA => S01_AXI_WDATA, - S_AXI_WSTRB => S01_AXI_WSTRB, - S_AXI_WLAST => S01_AXI_WLAST, + S_AXI_AWVALID => S01_AXI_AWVALID, + S_AXI_AWREADY => S01_AXI_AWREADY, + S_AXI_WDATA => S01_AXI_WDATA, + S_AXI_WSTRB => S01_AXI_WSTRB, + S_AXI_WLAST => S01_AXI_WLAST, --**S_AXI_WUSER => S01_AXI_WUSER, - S_AXI_WVALID => S01_AXI_WVALID, - S_AXI_WREADY => S01_AXI_WREADY, - S_AXI_BID => S01_AXI_BID, - S_AXI_BRESP => S01_AXI_BRESP, + S_AXI_WVALID => S01_AXI_WVALID, + S_AXI_WREADY => S01_AXI_WREADY, + S_AXI_BID => S01_AXI_BID, + S_AXI_BRESP => S01_AXI_BRESP, --**S_AXI_BUSER => S01_AXI_BUSER, S_AXI_BVALID => S01_AXI_BVALID, S_AXI_BREADY => S01_AXI_BREADY, @@ -416,69 +415,69 @@ scalp_hl2_S01_AXI_inst : scalp_hl2_S01_AXI S_AXI_ARQOS => S01_AXI_ARQOS, S_AXI_ARREGION => S01_AXI_ARREGION, --**S_AXI_ARUSER => S01_AXI_ARUSER, - S_AXI_ARVALID => S01_AXI_ARVALID, - S_AXI_ARREADY => S01_AXI_ARREADY, - S_AXI_RID => S01_AXI_RID, - S_AXI_RDATA => S01_AXI_RDATA, - S_AXI_RRESP => S01_AXI_RRESP, - S_AXI_RLAST => S01_AXI_RLAST, + S_AXI_ARVALID => S01_AXI_ARVALID, + S_AXI_ARREADY => S01_AXI_ARREADY, + S_AXI_RID => S01_AXI_RID, + S_AXI_RDATA => S01_AXI_RDATA, + S_AXI_RRESP => S01_AXI_RRESP, + S_AXI_RLAST => S01_AXI_RLAST, --**S_AXI_RUSER => S01_AXI_RUSER, - S_AXI_RVALID => S01_AXI_RVALID, - S_AXI_RREADY => S01_AXI_RREADY + S_AXI_RVALID => S01_AXI_RVALID, + S_AXI_RREADY => S01_AXI_RREADY ); -- Add user logic here -- Instantiation -scalp_hl2_ctrl_inst : scalp_hl2_ctrl - generic map ( - G_PORT_COUNT => G_PORT_COUNT + scalp_hl2_ctrl_inst : scalp_hl2_ctrl + generic map( + G_PORT_COUNT => G_PORT_COUNT ) - port map ( - i_clk => AXI_ACLK, - i_nrst => AXI_ARESETN, + port map( + i_clk => AXI_ACLK, + i_nrst => AXI_ARESETN, -- Config registers - ir_mab_clk => s_mab_clk, - ir_break_clk => s_break_clk, - ir_bit_clk => s_bit_clk, - ir_chan_count => s_chan_count, - ir_global_en => s_global_en, - ir_sof_value => s_sof_value, - ir_idl_value => s_idl_value, - ir_chan_en => s_chan_en, + ir_mab_clk => s_mab_clk, + ir_break_clk => s_break_clk, + ir_bit_clk => s_bit_clk, + ir_chan_count => s_chan_count, + ir_global_en => s_global_en, + ir_sof_value => s_sof_value, + ir_idl_value => s_idl_value, + ir_chan_en => s_chan_en, -- Data bus - i_data => s_dmx_data, - o_addr => s_dmx_addr, - o_rden => s_dmx_rden, + i_data => s_dmx_data, + o_addr => s_dmx_addr, + o_rden => s_dmx_rden, -- Dmx - o_dmx => dmx_out + o_dmx => dmx_out ); --- BRAM instance -scalp_hl2_bram_i: scalp_hl2_bram - generic map ( - G_PORT_COUNT => G_PORT_COUNT + -- BRAM instance + scalp_hl2_bram_i : scalp_hl2_bram + generic map( + G_PORT_COUNT => G_PORT_COUNT ) - port map ( - i_clk => AXI_ACLK, - i_nrst => AXI_ARESETN, + port map( + i_clk => AXI_ACLK, + i_nrst => AXI_ARESETN, -- AXI Ports Data bus - o_axi_data => s_axi_bram_rdata, - i_axi_addr => s_axi_bram_addr, - i_axi_data => s_axi_bram_wdata, - i_axi_en => s_axi_bram_en, - i_axi_we => s_axi_bram_we, + o_axi_data => s_axi_bram_rdata, + i_axi_addr => s_axi_bram_addr, + i_axi_data => s_axi_bram_wdata, + i_axi_en => s_axi_bram_en, + i_axi_we => s_axi_bram_we, -- DMX Ports Data bus - o_dmx_data => s_dmx_data, - i_dmx_addr => s_dmx_addr, - i_dmx_rden => s_dmx_rden + o_dmx_data => s_dmx_data, + i_dmx_addr => s_dmx_addr, + i_dmx_rden => s_dmx_rden ); -- User logic ends -end arch; +end arch; \ No newline at end of file diff --git a/ips/hw/scalp_hl2/src/hdl/scalp_hl2_S00_AXI.vhd b/ips/hw/scalp_hl2/src/hdl/scalp_hl2_S00_AXI.vhd index 3420974..0b13d35 100755 --- a/ips/hw/scalp_hl2/src/hdl/scalp_hl2_S00_AXI.vhd +++ b/ips/hw/scalp_hl2/src/hdl/scalp_hl2_S00_AXI.vhd @@ -1,3 +1,24 @@ +---------------------------------------------------------------------------------- +-- _ _ +-- | |_ ___ _ __(_)__ _ +-- | ' \/ -_) '_ \ / _` | +-- |_||_\___| .__/_\__,_| +-- |_| +-- +---------------------------------------------------------------------------------- +-- +-- Company: hepia +-- Author: Quentin Berthet <quentin.berthet@hesge.ch +-- +-- Module Name: scalp_hl2_S00_AXI +-- Target Device: hepia-cores.ch:scalp_node:part0:0.1 xc7z015clg485-2 +-- Tool version: 2019.2 +-- Description: AXIlite configuration register bank +-- +-- Last update: 2020/12/17 12:10:01 +-- +--------------------------------------------------------------------------------- + library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; @@ -6,437 +27,433 @@ library xil_defaultlib; use xil_defaultlib.scalp_hl2_pkg.all; entity scalp_hl2_S00_AXI is - generic ( - -- Users to add parameters here - G_PORT_COUNT : integer := 1; - -- User parameters ends - -- Do not modify the parameters beyond this line + generic ( + -- Users to add parameters here + G_PORT_COUNT : integer := 1; + -- User parameters ends + -- Do not modify the parameters beyond this line - -- Width of S_AXI data bus - C_S_AXI_DATA_WIDTH : integer := 32; - -- Width of S_AXI address bus - C_S_AXI_ADDR_WIDTH : integer := 4 - ); - port ( - -- Users to add ports here - -- Config registers - ir_mab_clk : out std_logic_vector(C_REG_MAB_CLK_SIZE-1 downto 0); - ir_break_clk : out std_logic_vector(C_REG_BREAK_CLK_SIZE-1 downto 0); - ir_bit_clk : out std_logic_vector(C_REG_BIT_CLK_SIZE-1 downto 0); - ir_chan_count : out std_logic_vector(C_REG_CHAN_COUNT_SIZE-1 downto 0); - ir_global_en : out std_logic_vector(C_REG_GLOBAL_EN_SIZE-1 downto 0); - ir_sof_value : out std_logic_vector((C_REG_SOF_VALUE_SIZE*G_PORT_COUNT)-1 downto 0); - ir_idl_value : out std_logic_vector((C_REG_IDL_SIZE*G_PORT_COUNT)-1 downto 0); - ir_chan_en : out std_logic_vector((C_REG_EN_SIZE*G_PORT_COUNT)-1 downto 0); - -- User ports ends - -- Do not modify the ports beyond this line + -- Width of S_AXI data bus + C_S_AXI_DATA_WIDTH : integer := 32; + -- Width of S_AXI address bus + C_S_AXI_ADDR_WIDTH : integer := 4 + ); + port ( + -- Users to add ports here + -- Config registers + ir_mab_clk : out std_logic_vector(C_REG_MAB_CLK_SIZE - 1 downto 0); + ir_break_clk : out std_logic_vector(C_REG_BREAK_CLK_SIZE - 1 downto 0); + ir_bit_clk : out std_logic_vector(C_REG_BIT_CLK_SIZE - 1 downto 0); + ir_chan_count : out std_logic_vector(C_REG_CHAN_COUNT_SIZE - 1 downto 0); + ir_global_en : out std_logic_vector(C_REG_GLOBAL_EN_SIZE - 1 downto 0); + ir_sof_value : out std_logic_vector((C_REG_SOF_VALUE_SIZE * G_PORT_COUNT) - 1 downto 0); + ir_idl_value : out std_logic_vector((C_REG_IDL_SIZE * G_PORT_COUNT) - 1 downto 0); + ir_chan_en : out std_logic_vector((C_REG_EN_SIZE * G_PORT_COUNT) - 1 downto 0); + -- User ports ends + -- Do not modify the ports beyond this line - -- Global Clock Signal - S_AXI_ACLK : in std_logic; - -- Global Reset Signal. This Signal is Active LOW - S_AXI_ARESETN : in std_logic; - -- Write address (issued by master, acceped by Slave) - S_AXI_AWADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0); - -- Write channel Protection type. This signal indicates the - -- privilege and security level of the transaction, and whether - -- the transaction is a data access or an instruction access. - S_AXI_AWPROT : in std_logic_vector(2 downto 0); - -- Write address valid. This signal indicates that the master signaling - -- valid write address and control information. - S_AXI_AWVALID : in std_logic; - -- Write address ready. This signal indicates that the slave is ready - -- to accept an address and associated control signals. - S_AXI_AWREADY : out std_logic; - -- Write data (issued by master, acceped by Slave) - S_AXI_WDATA : in std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); - -- Write strobes. This signal indicates which byte lanes hold - -- valid data. There is one write strobe bit for each eight - -- bits of the write data bus. - S_AXI_WSTRB : in std_logic_vector((C_S_AXI_DATA_WIDTH/8)-1 downto 0); - -- Write valid. This signal indicates that valid write - -- data and strobes are available. - S_AXI_WVALID : in std_logic; - -- Write ready. This signal indicates that the slave - -- can accept the write data. - S_AXI_WREADY : out std_logic; - -- Write response. This signal indicates the status - -- of the write transaction. - S_AXI_BRESP : out std_logic_vector(1 downto 0); - -- Write response valid. This signal indicates that the channel - -- is signaling a valid write response. - S_AXI_BVALID : out std_logic; - -- Response ready. This signal indicates that the master - -- can accept a write response. - S_AXI_BREADY : in std_logic; - -- Read address (issued by master, acceped by Slave) - S_AXI_ARADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0); - -- Protection type. This signal indicates the privilege - -- and security level of the transaction, and whether the - -- transaction is a data access or an instruction access. - S_AXI_ARPROT : in std_logic_vector(2 downto 0); - -- Read address valid. This signal indicates that the channel - -- is signaling valid read address and control information. - S_AXI_ARVALID : in std_logic; - -- Read address ready. This signal indicates that the slave is - -- ready to accept an address and associated control signals. - S_AXI_ARREADY : out std_logic; - -- Read data (issued by slave) - S_AXI_RDATA : out std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); - -- Read response. This signal indicates the status of the - -- read transfer. - S_AXI_RRESP : out std_logic_vector(1 downto 0); - -- Read valid. This signal indicates that the channel is - -- signaling the required read data. - S_AXI_RVALID : out std_logic; - -- Read ready. This signal indicates that the master can - -- accept the read data and response information. - S_AXI_RREADY : in std_logic - ); + -- Global Clock Signal + S_AXI_ACLK : in std_logic; + -- Global Reset Signal. This Signal is Active LOW + S_AXI_ARESETN : in std_logic; + -- Write address (issued by master, acceped by Slave) + S_AXI_AWADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH - 1 downto 0); + -- Write channel Protection type. This signal indicates the + -- privilege and security level of the transaction, and whether + -- the transaction is a data access or an instruction access. + S_AXI_AWPROT : in std_logic_vector(2 downto 0); + -- Write address valid. This signal indicates that the master signaling + -- valid write address and control information. + S_AXI_AWVALID : in std_logic; + -- Write address ready. This signal indicates that the slave is ready + -- to accept an address and associated control signals. + S_AXI_AWREADY : out std_logic; + -- Write data (issued by master, acceped by Slave) + S_AXI_WDATA : in std_logic_vector(C_S_AXI_DATA_WIDTH - 1 downto 0); + -- Write strobes. This signal indicates which byte lanes hold + -- valid data. There is one write strobe bit for each eight + -- bits of the write data bus. + S_AXI_WSTRB : in std_logic_vector((C_S_AXI_DATA_WIDTH/8) - 1 downto 0); + -- Write valid. This signal indicates that valid write + -- data and strobes are available. + S_AXI_WVALID : in std_logic; + -- Write ready. This signal indicates that the slave + -- can accept the write data. + S_AXI_WREADY : out std_logic; + -- Write response. This signal indicates the status + -- of the write transaction. + S_AXI_BRESP : out std_logic_vector(1 downto 0); + -- Write response valid. This signal indicates that the channel + -- is signaling a valid write response. + S_AXI_BVALID : out std_logic; + -- Response ready. This signal indicates that the master + -- can accept a write response. + S_AXI_BREADY : in std_logic; + -- Read address (issued by master, acceped by Slave) + S_AXI_ARADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH - 1 downto 0); + -- Protection type. This signal indicates the privilege + -- and security level of the transaction, and whether the + -- transaction is a data access or an instruction access. + S_AXI_ARPROT : in std_logic_vector(2 downto 0); + -- Read address valid. This signal indicates that the channel + -- is signaling valid read address and control information. + S_AXI_ARVALID : in std_logic; + -- Read address ready. This signal indicates that the slave is + -- ready to accept an address and associated control signals. + S_AXI_ARREADY : out std_logic; + -- Read data (issued by slave) + S_AXI_RDATA : out std_logic_vector(C_S_AXI_DATA_WIDTH - 1 downto 0); + -- Read response. This signal indicates the status of the + -- read transfer. + S_AXI_RRESP : out std_logic_vector(1 downto 0); + -- Read valid. This signal indicates that the channel is + -- signaling the required read data. + S_AXI_RVALID : out std_logic; + -- Read ready. This signal indicates that the master can + -- accept the read data and response information. + S_AXI_RREADY : in std_logic + ); end scalp_hl2_S00_AXI; architecture arch_imp of scalp_hl2_S00_AXI is - -- AXI4LITE signals - signal axi_awaddr : std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0); - signal axi_awready : std_logic; - signal axi_wready : std_logic; - signal axi_bresp : std_logic_vector(1 downto 0); - signal axi_bvalid : std_logic; - signal axi_araddr : std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0); - signal axi_arready : std_logic; - signal axi_rdata : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); - signal axi_rresp : std_logic_vector(1 downto 0); - signal axi_rvalid : std_logic; + -- AXI4LITE signals + signal axi_awaddr : std_logic_vector(C_S_AXI_ADDR_WIDTH - 1 downto 0); + signal axi_awready : std_logic; + signal axi_wready : std_logic; + signal axi_bresp : std_logic_vector(1 downto 0); + signal axi_bvalid : std_logic; + signal axi_araddr : std_logic_vector(C_S_AXI_ADDR_WIDTH - 1 downto 0); + signal axi_arready : std_logic; + signal axi_rdata : std_logic_vector(C_S_AXI_DATA_WIDTH - 1 downto 0); + signal axi_rresp : std_logic_vector(1 downto 0); + signal axi_rvalid : std_logic; - -- Example-specific design signals - -- local parameter for addressing 32 bit / 64 bit C_S_AXI_DATA_WIDTH - -- ADDR_LSB is used for addressing 32/64 bit registers/memories - -- ADDR_LSB = 2 for 32 bits (n downto 2) - -- ADDR_LSB = 3 for 64 bits (n downto 3) - constant ADDR_LSB : integer := (C_S_AXI_DATA_WIDTH/32)+ 1; - constant OPT_MEM_ADDR_BITS : integer := 1; - ------------------------------------------------ - ---- Signals for user logic register space example - -------------------------------------------------- - ---- Number of Slave Registers 4 - --signal slv_reg0 : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); - --signal slv_reg1 : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); - --signal slv_reg2 : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); - --signal slv_reg3 : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); - -- Config registers - signal slv_reg_mab_clk : std_logic_vector(C_REG_MAB_CLK_SIZE-1 downto 0); - signal slv_reg_break_clk : std_logic_vector(C_REG_BREAK_CLK_SIZE-1 downto 0); - signal slv_reg_bit_clk : std_logic_vector(C_REG_BIT_CLK_SIZE-1 downto 0); - signal slv_reg_chan_count : std_logic_vector(C_REG_CHAN_COUNT_SIZE-1 downto 0); - signal slv_reg_global_en : std_logic_vector(C_REG_GLOBAL_EN_SIZE-1 downto 0); - signal slv_reg_sof_value : std_logic_vector((C_REG_SOF_VALUE_SIZE*G_PORT_COUNT)-1 downto 0); - signal slv_reg_idl_value : std_logic_vector((C_REG_IDL_SIZE*G_PORT_COUNT)-1 downto 0); - signal slv_reg_chan_en : std_logic_vector((C_REG_EN_SIZE*G_PORT_COUNT)-1 downto 0); - - - signal slv_reg_rden : std_logic; - signal slv_reg_wren : std_logic; - signal reg_data_out : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); - signal byte_index : integer; - signal aw_en : std_logic; + -- Example-specific design signals + -- local parameter for addressing 32 bit / 64 bit C_S_AXI_DATA_WIDTH + -- ADDR_LSB is used for addressing 32/64 bit registers/memories + -- ADDR_LSB = 2 for 32 bits (n downto 2) + -- ADDR_LSB = 3 for 64 bits (n downto 3) + constant ADDR_LSB : integer := (C_S_AXI_DATA_WIDTH/32) + 1; + constant OPT_MEM_ADDR_BITS : integer := 1; + ------------------------------------------------ + ---- Signals for user logic register space example + -------------------------------------------------- + ---- Number of Slave Registers 4 + --signal slv_reg0 : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); + --signal slv_reg1 : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); + --signal slv_reg2 : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); + --signal slv_reg3 : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); + -- Config registers + signal slv_reg_mab_clk : std_logic_vector(C_REG_MAB_CLK_SIZE - 1 downto 0); + signal slv_reg_break_clk : std_logic_vector(C_REG_BREAK_CLK_SIZE - 1 downto 0); + signal slv_reg_bit_clk : std_logic_vector(C_REG_BIT_CLK_SIZE - 1 downto 0); + signal slv_reg_chan_count : std_logic_vector(C_REG_CHAN_COUNT_SIZE - 1 downto 0); + signal slv_reg_global_en : std_logic_vector(C_REG_GLOBAL_EN_SIZE - 1 downto 0); + signal slv_reg_sof_value : std_logic_vector((C_REG_SOF_VALUE_SIZE * G_PORT_COUNT) - 1 downto 0); + signal slv_reg_idl_value : std_logic_vector((C_REG_IDL_SIZE * G_PORT_COUNT) - 1 downto 0); + signal slv_reg_chan_en : std_logic_vector((C_REG_EN_SIZE * G_PORT_COUNT) - 1 downto 0); + signal slv_reg_rden : std_logic; + signal slv_reg_wren : std_logic; + signal reg_data_out : std_logic_vector(C_S_AXI_DATA_WIDTH - 1 downto 0); + signal byte_index : integer; + signal aw_en : std_logic; begin - -- I/O Connections assignments - - S_AXI_AWREADY <= axi_awready; - S_AXI_WREADY <= axi_wready; - S_AXI_BRESP <= axi_bresp; - S_AXI_BVALID <= axi_bvalid; - S_AXI_ARREADY <= axi_arready; - S_AXI_RDATA <= axi_rdata; - S_AXI_RRESP <= axi_rresp; - S_AXI_RVALID <= axi_rvalid; - -- Implement axi_awready generation - -- axi_awready is asserted for one S_AXI_ACLK clock cycle when both - -- S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_awready is - -- de-asserted when reset is low. + -- I/O Connections assignments - process (S_AXI_ACLK) - begin - if rising_edge(S_AXI_ACLK) then - if S_AXI_ARESETN = '0' then - axi_awready <= '0'; - aw_en <= '1'; - else - if (axi_awready = '0' and S_AXI_AWVALID = '1' and S_AXI_WVALID = '1' and aw_en = '1') then - -- slave is ready to accept write address when - -- there is a valid write address and write data - -- on the write address and data bus. This design - -- expects no outstanding transactions. - axi_awready <= '1'; - elsif (S_AXI_BREADY = '1' and axi_bvalid = '1') then - aw_en <= '1'; - axi_awready <= '0'; - else - axi_awready <= '0'; - end if; - end if; - end if; - end process; + S_AXI_AWREADY <= axi_awready; + S_AXI_WREADY <= axi_wready; + S_AXI_BRESP <= axi_bresp; + S_AXI_BVALID <= axi_bvalid; + S_AXI_ARREADY <= axi_arready; + S_AXI_RDATA <= axi_rdata; + S_AXI_RRESP <= axi_rresp; + S_AXI_RVALID <= axi_rvalid; + -- Implement axi_awready generation + -- axi_awready is asserted for one S_AXI_ACLK clock cycle when both + -- S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_awready is + -- de-asserted when reset is low. - -- Implement axi_awaddr latching - -- This process is used to latch the address when both - -- S_AXI_AWVALID and S_AXI_WVALID are valid. + process (S_AXI_ACLK) + begin + if rising_edge(S_AXI_ACLK) then + if S_AXI_ARESETN = '0' then + axi_awready <= '0'; + aw_en <= '1'; + else + if (axi_awready = '0' and S_AXI_AWVALID = '1' and S_AXI_WVALID = '1' and aw_en = '1') then + -- slave is ready to accept write address when + -- there is a valid write address and write data + -- on the write address and data bus. This design + -- expects no outstanding transactions. + axi_awready <= '1'; + elsif (S_AXI_BREADY = '1' and axi_bvalid = '1') then + aw_en <= '1'; + axi_awready <= '0'; + else + axi_awready <= '0'; + end if; + end if; + end if; + end process; - process (S_AXI_ACLK) - begin - if rising_edge(S_AXI_ACLK) then - if S_AXI_ARESETN = '0' then - axi_awaddr <= (others => '0'); - else - if (axi_awready = '0' and S_AXI_AWVALID = '1' and S_AXI_WVALID = '1' and aw_en = '1') then - -- Write Address latching - axi_awaddr <= S_AXI_AWADDR; - end if; - end if; - end if; - end process; + -- Implement axi_awaddr latching + -- This process is used to latch the address when both + -- S_AXI_AWVALID and S_AXI_WVALID are valid. - -- Implement axi_wready generation - -- axi_wready is asserted for one S_AXI_ACLK clock cycle when both - -- S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_wready is - -- de-asserted when reset is low. + process (S_AXI_ACLK) + begin + if rising_edge(S_AXI_ACLK) then + if S_AXI_ARESETN = '0' then + axi_awaddr <= (others => '0'); + else + if (axi_awready = '0' and S_AXI_AWVALID = '1' and S_AXI_WVALID = '1' and aw_en = '1') then + -- Write Address latching + axi_awaddr <= S_AXI_AWADDR; + end if; + end if; + end if; + end process; - process (S_AXI_ACLK) - begin - if rising_edge(S_AXI_ACLK) then - if S_AXI_ARESETN = '0' then - axi_wready <= '0'; - else - if (axi_wready = '0' and S_AXI_WVALID = '1' and S_AXI_AWVALID = '1' and aw_en = '1') then - -- slave is ready to accept write data when - -- there is a valid write address and write data - -- on the write address and data bus. This design - -- expects no outstanding transactions. - axi_wready <= '1'; - else - axi_wready <= '0'; - end if; - end if; - end if; - end process; + -- Implement axi_wready generation + -- axi_wready is asserted for one S_AXI_ACLK clock cycle when both + -- S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_wready is + -- de-asserted when reset is low. - -- Implement memory mapped register select and write logic generation - -- The write data is accepted and written to memory mapped registers when - -- axi_awready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted. Write strobes are used to - -- select byte enables of slave registers while writing. - -- These registers are cleared when reset (active low) is applied. - -- Slave register write enable is asserted when valid address and data are available - -- and the slave is ready to accept the write address and write data. - slv_reg_wren <= axi_wready and S_AXI_WVALID and axi_awready and S_AXI_AWVALID ; + process (S_AXI_ACLK) + begin + if rising_edge(S_AXI_ACLK) then + if S_AXI_ARESETN = '0' then + axi_wready <= '0'; + else + if (axi_wready = '0' and S_AXI_WVALID = '1' and S_AXI_AWVALID = '1' and aw_en = '1') then + -- slave is ready to accept write data when + -- there is a valid write address and write data + -- on the write address and data bus. This design + -- expects no outstanding transactions. + axi_wready <= '1'; + else + axi_wready <= '0'; + end if; + end if; + end if; + end process; - process (S_AXI_ACLK) - variable loc_addr :std_logic_vector(OPT_MEM_ADDR_BITS downto 0); - begin - if rising_edge(S_AXI_ACLK) then - if S_AXI_ARESETN = '0' then - -- Assign reset values - slv_reg_mab_clk <= std_logic_vector(to_unsigned(C_REG_MAB_CLK_RESET_VAL, C_REG_MAB_CLK_SIZE)); - slv_reg_break_clk <= std_logic_vector(to_unsigned(C_REG_BREAK_CLK_RESET_VAL, C_REG_BREAK_CLK_SIZE)); - slv_reg_bit_clk <= std_logic_vector(to_unsigned(C_REG_BIT_CLK_RESET_VAL, C_REG_BIT_CLK_SIZE)); - slv_reg_chan_count <= std_logic_vector(to_unsigned(C_REG_CHAN_COUNT_RESET_VAL, C_REG_CHAN_COUNT_SIZE)); - slv_reg_global_en <= std_logic_vector(to_unsigned(C_REG_GLOBAL_EN_RESET_VAL, C_REG_GLOBAL_EN_SIZE)); - -- FIXME use package reset value - slv_reg_sof_value <= (others => '0'); - slv_reg_idl_value <= (others => '0'); - slv_reg_chan_en <= (others => '1'); - else - loc_addr := axi_awaddr(ADDR_LSB + OPT_MEM_ADDR_BITS downto ADDR_LSB); - if (slv_reg_wren = '1') then - case loc_addr is - -- read only 00 register - - when b"01" => -- Global clock config register : 0x0004 - if ( S_AXI_WSTRB(0) = '1' ) then - slv_reg_bit_clk(7 downto 0) <= S_AXI_WDATA(7 downto 0); - end if; - if ( S_AXI_WSTRB(1) = '1' ) then - slv_reg_bit_clk(15 downto 8) <= S_AXI_WDATA(15 downto 8); - end if; - when b"10" => - if ( S_AXI_WSTRB(0) = '1' ) then - slv_reg_break_clk(7 downto 0) <= S_AXI_WDATA(7 downto 0); - end if; - if ( S_AXI_WSTRB(1) = '1' ) then - slv_reg_break_clk(15 downto 8) <= S_AXI_WDATA(15 downto 8); - end if; - if ( S_AXI_WSTRB(2) = '1' ) then - slv_reg_mab_clk(7 downto 0) <= S_AXI_WDATA(23 downto 16); - end if; - if ( S_AXI_WSTRB(3) = '1' ) then - slv_reg_mab_clk(15 downto 8) <= S_AXI_WDATA(31 downto 24); - end if; - when b"11" => - if ( S_AXI_WSTRB(0) = '1' ) then - slv_reg_global_en(0 downto 0) <= S_AXI_WDATA(0 downto 0); - end if; - if ( S_AXI_WSTRB(2) = '1' ) then - slv_reg_chan_count(7 downto 0) <= S_AXI_WDATA(23 downto 16); - end if; - if ( S_AXI_WSTRB(3) = '1' ) then - slv_reg_chan_count(11 downto 8) <= S_AXI_WDATA(27 downto 24); - end if; - when others => - slv_reg_mab_clk <= slv_reg_mab_clk; - slv_reg_break_clk <= slv_reg_break_clk; - slv_reg_bit_clk <= slv_reg_bit_clk; - slv_reg_chan_count <= slv_reg_chan_count; - slv_reg_global_en <= slv_reg_global_en; - slv_reg_sof_value <= slv_reg_sof_value; - slv_reg_idl_value <= slv_reg_idl_value; - slv_reg_chan_en <= slv_reg_chan_en; - end case; - end if; - end if; - end if; - end process; + -- Implement memory mapped register select and write logic generation + -- The write data is accepted and written to memory mapped registers when + -- axi_awready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted. Write strobes are used to + -- select byte enables of slave registers while writing. + -- These registers are cleared when reset (active low) is applied. + -- Slave register write enable is asserted when valid address and data are available + -- and the slave is ready to accept the write address and write data. + slv_reg_wren <= axi_wready and S_AXI_WVALID and axi_awready and S_AXI_AWVALID; - -- Implement write response logic generation - -- The write response and response valid signals are asserted by the slave - -- when axi_wready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted. - -- This marks the acceptance of address and indicates the status of - -- write transaction. + process (S_AXI_ACLK) + variable loc_addr : std_logic_vector(OPT_MEM_ADDR_BITS downto 0); + begin + if rising_edge(S_AXI_ACLK) then + if S_AXI_ARESETN = '0' then + -- Assign reset values + slv_reg_mab_clk <= std_logic_vector(to_unsigned(C_REG_MAB_CLK_RESET_VAL, C_REG_MAB_CLK_SIZE)); + slv_reg_break_clk <= std_logic_vector(to_unsigned(C_REG_BREAK_CLK_RESET_VAL, C_REG_BREAK_CLK_SIZE)); + slv_reg_bit_clk <= std_logic_vector(to_unsigned(C_REG_BIT_CLK_RESET_VAL, C_REG_BIT_CLK_SIZE)); + slv_reg_chan_count <= std_logic_vector(to_unsigned(C_REG_CHAN_COUNT_RESET_VAL, C_REG_CHAN_COUNT_SIZE)); + slv_reg_global_en <= std_logic_vector(to_unsigned(C_REG_GLOBAL_EN_RESET_VAL, C_REG_GLOBAL_EN_SIZE)); + -- FIXME use package reset value + slv_reg_sof_value <= (others => '0'); + slv_reg_idl_value <= (others => '0'); + slv_reg_chan_en <= (others => '1'); + else + loc_addr := axi_awaddr(ADDR_LSB + OPT_MEM_ADDR_BITS downto ADDR_LSB); + if (slv_reg_wren = '1') then + case loc_addr is + -- read only 00 register - process (S_AXI_ACLK) - begin - if rising_edge(S_AXI_ACLK) then - if S_AXI_ARESETN = '0' then - axi_bvalid <= '0'; - axi_bresp <= "00"; --need to work more on the responses - else - if (axi_awready = '1' and S_AXI_AWVALID = '1' and axi_wready = '1' and S_AXI_WVALID = '1' and axi_bvalid = '0' ) then - axi_bvalid <= '1'; - axi_bresp <= "00"; - elsif (S_AXI_BREADY = '1' and axi_bvalid = '1') then --check if bready is asserted while bvalid is high) - axi_bvalid <= '0'; -- (there is a possibility that bready is always asserted high) - end if; - end if; - end if; - end process; + when b"01" => -- Global clock config register : 0x0004 + if (S_AXI_WSTRB(0) = '1') then + slv_reg_bit_clk(7 downto 0) <= S_AXI_WDATA(7 downto 0); + end if; + if (S_AXI_WSTRB(1) = '1') then + slv_reg_bit_clk(15 downto 8) <= S_AXI_WDATA(15 downto 8); + end if; + when b"10" => + if (S_AXI_WSTRB(0) = '1') then + slv_reg_break_clk(7 downto 0) <= S_AXI_WDATA(7 downto 0); + end if; + if (S_AXI_WSTRB(1) = '1') then + slv_reg_break_clk(15 downto 8) <= S_AXI_WDATA(15 downto 8); + end if; + if (S_AXI_WSTRB(2) = '1') then + slv_reg_mab_clk(7 downto 0) <= S_AXI_WDATA(23 downto 16); + end if; + if (S_AXI_WSTRB(3) = '1') then + slv_reg_mab_clk(15 downto 8) <= S_AXI_WDATA(31 downto 24); + end if; + when b"11" => + if (S_AXI_WSTRB(0) = '1') then + slv_reg_global_en(0 downto 0) <= S_AXI_WDATA(0 downto 0); + end if; + if (S_AXI_WSTRB(2) = '1') then + slv_reg_chan_count(7 downto 0) <= S_AXI_WDATA(23 downto 16); + end if; + if (S_AXI_WSTRB(3) = '1') then + slv_reg_chan_count(11 downto 8) <= S_AXI_WDATA(27 downto 24); + end if; + when others => + slv_reg_mab_clk <= slv_reg_mab_clk; + slv_reg_break_clk <= slv_reg_break_clk; + slv_reg_bit_clk <= slv_reg_bit_clk; + slv_reg_chan_count <= slv_reg_chan_count; + slv_reg_global_en <= slv_reg_global_en; + slv_reg_sof_value <= slv_reg_sof_value; + slv_reg_idl_value <= slv_reg_idl_value; + slv_reg_chan_en <= slv_reg_chan_en; + end case; + end if; + end if; + end if; + end process; - -- Implement axi_arready generation - -- axi_arready is asserted for one S_AXI_ACLK clock cycle when - -- S_AXI_ARVALID is asserted. axi_awready is - -- de-asserted when reset (active low) is asserted. - -- The read address is also latched when S_AXI_ARVALID is - -- asserted. axi_araddr is reset to zero on reset assertion. + -- Implement write response logic generation + -- The write response and response valid signals are asserted by the slave + -- when axi_wready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted. + -- This marks the acceptance of address and indicates the status of + -- write transaction. - process (S_AXI_ACLK) - begin - if rising_edge(S_AXI_ACLK) then - if S_AXI_ARESETN = '0' then - axi_arready <= '0'; - axi_araddr <= (others => '1'); - else - if (axi_arready = '0' and S_AXI_ARVALID = '1') then - -- indicates that the slave has acceped the valid read address - axi_arready <= '1'; - -- Read Address latching - axi_araddr <= S_AXI_ARADDR; - else - axi_arready <= '0'; - end if; - end if; - end if; - end process; + process (S_AXI_ACLK) + begin + if rising_edge(S_AXI_ACLK) then + if S_AXI_ARESETN = '0' then + axi_bvalid <= '0'; + axi_bresp <= "00"; --need to work more on the responses + else + if (axi_awready = '1' and S_AXI_AWVALID = '1' and axi_wready = '1' and S_AXI_WVALID = '1' and axi_bvalid = '0') then + axi_bvalid <= '1'; + axi_bresp <= "00"; + elsif (S_AXI_BREADY = '1' and axi_bvalid = '1') then --check if bready is asserted while bvalid is high) + axi_bvalid <= '0'; -- (there is a possibility that bready is always asserted high) + end if; + end if; + end if; + end process; - -- Implement axi_arvalid generation - -- axi_rvalid is asserted for one S_AXI_ACLK clock cycle when both - -- S_AXI_ARVALID and axi_arready are asserted. The slave registers - -- data are available on the axi_rdata bus at this instance. The - -- assertion of axi_rvalid marks the validity of read data on the - -- bus and axi_rresp indicates the status of read transaction.axi_rvalid - -- is deasserted on reset (active low). axi_rresp and axi_rdata are - -- cleared to zero on reset (active low). - process (S_AXI_ACLK) - begin - if rising_edge(S_AXI_ACLK) then - if S_AXI_ARESETN = '0' then - axi_rvalid <= '0'; - axi_rresp <= "00"; - else - if (axi_arready = '1' and S_AXI_ARVALID = '1' and axi_rvalid = '0') then - -- Valid read data is available at the read data bus - axi_rvalid <= '1'; - axi_rresp <= "00"; -- 'OKAY' response - elsif (axi_rvalid = '1' and S_AXI_RREADY = '1') then - -- Read data is accepted by the master - axi_rvalid <= '0'; - end if; - end if; - end if; - end process; + -- Implement axi_arready generation + -- axi_arready is asserted for one S_AXI_ACLK clock cycle when + -- S_AXI_ARVALID is asserted. axi_awready is + -- de-asserted when reset (active low) is asserted. + -- The read address is also latched when S_AXI_ARVALID is + -- asserted. axi_araddr is reset to zero on reset assertion. - -- Implement memory mapped register select and read logic generation - -- Slave register read enable is asserted when valid address is available - -- and the slave is ready to accept the read address. - slv_reg_rden <= axi_arready and S_AXI_ARVALID and (not axi_rvalid) ; + process (S_AXI_ACLK) + begin + if rising_edge(S_AXI_ACLK) then + if S_AXI_ARESETN = '0' then + axi_arready <= '0'; + axi_araddr <= (others => '1'); + else + if (axi_arready = '0' and S_AXI_ARVALID = '1') then + -- indicates that the slave has acceped the valid read address + axi_arready <= '1'; + -- Read Address latching + axi_araddr <= S_AXI_ARADDR; + else + axi_arready <= '0'; + end if; + end if; + end if; + end process; - process (slv_reg_bit_clk, slv_reg_mab_clk, slv_reg_break_clk, slv_reg_chan_count, slv_reg_global_en, axi_araddr, S_AXI_ARESETN, slv_reg_rden) - variable loc_addr :std_logic_vector(OPT_MEM_ADDR_BITS downto 0); - begin - -- Address decoding for reading registers - loc_addr := axi_araddr(ADDR_LSB + OPT_MEM_ADDR_BITS downto ADDR_LSB); - case loc_addr is - when b"00" => - -- Info register : 0x0000 - reg_data_out <= (others => '0'); - reg_data_out(C_REG_PORT_COUNT_POS + C_REG_PORT_COUNT_SIZE - 1 downto C_REG_PORT_COUNT_POS) <= std_logic_vector(to_unsigned(G_PORT_COUNT, C_REG_PORT_COUNT_SIZE)); - reg_data_out(C_REG_IP_REV_MAJ_POS + C_REG_IP_REV_MAJ_SIZE - 1 downto C_REG_IP_REV_MAJ_POS) <= std_logic_vector(to_unsigned(C_REG_IP_REV_MAJ_RESET_VAL, C_REG_IP_REV_MAJ_SIZE)); - reg_data_out(C_REG_IP_REV_MIN_POS + C_REG_IP_REV_MIN_SIZE - 1 downto C_REG_IP_REV_MIN_POS) <= std_logic_vector(to_unsigned(C_REG_IP_REV_MIN_RESET_VAL, C_REG_IP_REV_MIN_SIZE)); - when b"01" => - -- Global clock config register : 0x0004 - reg_data_out <= (others => '0'); - reg_data_out(C_REG_BIT_CLK_POS + C_REG_BIT_CLK_SIZE - 1 downto C_REG_BIT_CLK_POS) <= slv_reg_bit_clk; - when b"10" => - -- Global break config register : 0x0008 - reg_data_out <= (others => '0'); - reg_data_out(C_REG_MAB_CLK_POS + C_REG_MAB_CLK_SIZE - 1 downto C_REG_MAB_CLK_POS) <= slv_reg_mab_clk; - reg_data_out(C_REG_BREAK_CLK_POS + C_REG_BREAK_CLK_SIZE - 1 downto C_REG_BREAK_CLK_POS) <= slv_reg_break_clk; - when b"11" => - -- Global control register - reg_data_out <= (others => '0'); - reg_data_out(C_REG_CHAN_COUNT_POS + C_REG_CHAN_COUNT_SIZE - 1 downto C_REG_CHAN_COUNT_POS) <= slv_reg_chan_count; - reg_data_out(C_REG_GLOBAL_EN_POS + C_REG_GLOBAL_EN_SIZE - 1 downto C_REG_GLOBAL_EN_POS) <= slv_reg_global_en; - when others => - -- FIXME find a way to read variable number of port registers - reg_data_out <= (others => '0'); - end case; - end process; + -- Implement axi_arvalid generation + -- axi_rvalid is asserted for one S_AXI_ACLK clock cycle when both + -- S_AXI_ARVALID and axi_arready are asserted. The slave registers + -- data are available on the axi_rdata bus at this instance. The + -- assertion of axi_rvalid marks the validity of read data on the + -- bus and axi_rresp indicates the status of read transaction.axi_rvalid + -- is deasserted on reset (active low). axi_rresp and axi_rdata are + -- cleared to zero on reset (active low). + process (S_AXI_ACLK) + begin + if rising_edge(S_AXI_ACLK) then + if S_AXI_ARESETN = '0' then + axi_rvalid <= '0'; + axi_rresp <= "00"; + else + if (axi_arready = '1' and S_AXI_ARVALID = '1' and axi_rvalid = '0') then + -- Valid read data is available at the read data bus + axi_rvalid <= '1'; + axi_rresp <= "00"; -- 'OKAY' response + elsif (axi_rvalid = '1' and S_AXI_RREADY = '1') then + -- Read data is accepted by the master + axi_rvalid <= '0'; + end if; + end if; + end if; + end process; - -- Output register or memory read data - process( S_AXI_ACLK ) is - begin - if (rising_edge (S_AXI_ACLK)) then - if ( S_AXI_ARESETN = '0' ) then - axi_rdata <= (others => '0'); - else - if (slv_reg_rden = '1') then - -- When there is a valid read address (S_AXI_ARVALID) with - -- acceptance of read address by the slave (axi_arready), - -- output the read dada - -- Read address mux - axi_rdata <= reg_data_out; -- register read data - end if; - end if; - end if; - end process; + -- Implement memory mapped register select and read logic generation + -- Slave register read enable is asserted when valid address is available + -- and the slave is ready to accept the read address. + slv_reg_rden <= axi_arready and S_AXI_ARVALID and (not axi_rvalid); + process (slv_reg_bit_clk, slv_reg_mab_clk, slv_reg_break_clk, slv_reg_chan_count, slv_reg_global_en, axi_araddr, S_AXI_ARESETN, slv_reg_rden) + variable loc_addr : std_logic_vector(OPT_MEM_ADDR_BITS downto 0); + begin + -- Address decoding for reading registers + loc_addr := axi_araddr(ADDR_LSB + OPT_MEM_ADDR_BITS downto ADDR_LSB); + case loc_addr is + when b"00" => + -- Info register : 0x0000 + reg_data_out <= (others => '0'); + reg_data_out(C_REG_PORT_COUNT_POS + C_REG_PORT_COUNT_SIZE - 1 downto C_REG_PORT_COUNT_POS) <= std_logic_vector(to_unsigned(G_PORT_COUNT, C_REG_PORT_COUNT_SIZE)); + reg_data_out(C_REG_IP_REV_MAJ_POS + C_REG_IP_REV_MAJ_SIZE - 1 downto C_REG_IP_REV_MAJ_POS) <= std_logic_vector(to_unsigned(C_REG_IP_REV_MAJ_RESET_VAL, C_REG_IP_REV_MAJ_SIZE)); + reg_data_out(C_REG_IP_REV_MIN_POS + C_REG_IP_REV_MIN_SIZE - 1 downto C_REG_IP_REV_MIN_POS) <= std_logic_vector(to_unsigned(C_REG_IP_REV_MIN_RESET_VAL, C_REG_IP_REV_MIN_SIZE)); + when b"01" => + -- Global clock config register : 0x0004 + reg_data_out <= (others => '0'); + reg_data_out(C_REG_BIT_CLK_POS + C_REG_BIT_CLK_SIZE - 1 downto C_REG_BIT_CLK_POS) <= slv_reg_bit_clk; + when b"10" => + -- Global break config register : 0x0008 + reg_data_out <= (others => '0'); + reg_data_out(C_REG_MAB_CLK_POS + C_REG_MAB_CLK_SIZE - 1 downto C_REG_MAB_CLK_POS) <= slv_reg_mab_clk; + reg_data_out(C_REG_BREAK_CLK_POS + C_REG_BREAK_CLK_SIZE - 1 downto C_REG_BREAK_CLK_POS) <= slv_reg_break_clk; + when b"11" => + -- Global control register + reg_data_out <= (others => '0'); + reg_data_out(C_REG_CHAN_COUNT_POS + C_REG_CHAN_COUNT_SIZE - 1 downto C_REG_CHAN_COUNT_POS) <= slv_reg_chan_count; + reg_data_out(C_REG_GLOBAL_EN_POS + C_REG_GLOBAL_EN_SIZE - 1 downto C_REG_GLOBAL_EN_POS) <= slv_reg_global_en; + when others => + -- FIXME find a way to read variable number of port registers + reg_data_out <= (others => '0'); + end case; + end process; - -- Add user logic here - ir_mab_clk <= slv_reg_mab_clk; - ir_break_clk <= slv_reg_break_clk; - ir_bit_clk <= slv_reg_bit_clk; - ir_chan_count <= slv_reg_chan_count; - ir_global_en <= slv_reg_global_en; - ir_sof_value <= slv_reg_sof_value; - ir_idl_value <= slv_reg_idl_value; - ir_chan_en <= slv_reg_chan_en; - -- User logic ends + -- Output register or memory read data + process (S_AXI_ACLK) is + begin + if (rising_edge (S_AXI_ACLK)) then + if (S_AXI_ARESETN = '0') then + axi_rdata <= (others => '0'); + else + if (slv_reg_rden = '1') then + -- When there is a valid read address (S_AXI_ARVALID) with + -- acceptance of read address by the slave (axi_arready), + -- output the read dada + -- Read address mux + axi_rdata <= reg_data_out; -- register read data + end if; + end if; + end if; + end process; + -- Add user logic here + ir_mab_clk <= slv_reg_mab_clk; + ir_break_clk <= slv_reg_break_clk; + ir_bit_clk <= slv_reg_bit_clk; + ir_chan_count <= slv_reg_chan_count; + ir_global_en <= slv_reg_global_en; + ir_sof_value <= slv_reg_sof_value; + ir_idl_value <= slv_reg_idl_value; + ir_chan_en <= slv_reg_chan_en; + -- User logic ends -end arch_imp; +end arch_imp; \ No newline at end of file diff --git a/ips/hw/scalp_hl2/src/hdl/scalp_hl2_S01_AXI.vhd b/ips/hw/scalp_hl2/src/hdl/scalp_hl2_S01_AXI.vhd index 57b23a6..a2d9b6e 100755 --- a/ips/hw/scalp_hl2/src/hdl/scalp_hl2_S01_AXI.vhd +++ b/ips/hw/scalp_hl2/src/hdl/scalp_hl2_S01_AXI.vhd @@ -1,3 +1,24 @@ +---------------------------------------------------------------------------------- +-- _ _ +-- | |_ ___ _ __(_)__ _ +-- | ' \/ -_) '_ \ / _` | +-- |_||_\___| .__/_\__,_| +-- |_| +-- +---------------------------------------------------------------------------------- +-- +-- Company: hepia +-- Author: Quentin Berthet <quentin.berthet@hesge.ch +-- +-- Module Name: scalp_hl2_S01_AXI +-- Target Device: hepia-cores.ch:scalp_node:part0:0.1 xc7z015clg485-2 +-- Tool version: 2019.2 +-- Description: AXI4 memory mapped BRAM access +-- +-- Last update: 2020/12/17 12:10:03 +-- +--------------------------------------------------------------------------------- + library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; @@ -5,77 +26,77 @@ use ieee.numeric_std.all; entity scalp_hl2_S01_AXI is generic ( -- Users to add parameters here - G_PORT_COUNT : integer := 1; + G_PORT_COUNT : integer := 1; -- User parameters ends -- Do not modify the parameters beyond this line -- Width of ID for for write address, write data, read address and read data - C_S_AXI_ID_WIDTH : integer := 1; + C_S_AXI_ID_WIDTH : integer := 1; -- Width of S_AXI data bus - C_S_AXI_DATA_WIDTH : integer := 32; + C_S_AXI_DATA_WIDTH : integer := 32; -- Width of S_AXI address bus - C_S_AXI_ADDR_WIDTH : integer := 19; + C_S_AXI_ADDR_WIDTH : integer := 19; -- Width of optional user defined signal in write address channel - C_S_AXI_AWUSER_WIDTH : integer := 0; + C_S_AXI_AWUSER_WIDTH : integer := 0; -- Width of optional user defined signal in read address channel - C_S_AXI_ARUSER_WIDTH : integer := 0; + C_S_AXI_ARUSER_WIDTH : integer := 0; -- Width of optional user defined signal in write data channel - C_S_AXI_WUSER_WIDTH : integer := 0; + C_S_AXI_WUSER_WIDTH : integer := 0; -- Width of optional user defined signal in read data channel - C_S_AXI_RUSER_WIDTH : integer := 0; + C_S_AXI_RUSER_WIDTH : integer := 0; -- Width of optional user defined signal in write response channel - C_S_AXI_BUSER_WIDTH : integer := 0 + C_S_AXI_BUSER_WIDTH : integer := 0 ); port ( -- BRAM signals - i_bram_rdata : in std_logic_vector(31 downto 0); - o_bram_addr : out std_logic_vector(16 downto 0); - o_bram_wdata : out std_logic_vector(31 downto 0); - o_bram_en : out std_logic; - o_bram_we : out std_logic_vector(3 downto 0); + i_bram_rdata : in std_logic_vector(31 downto 0); + o_bram_addr : out std_logic_vector(16 downto 0); + o_bram_wdata : out std_logic_vector(31 downto 0); + o_bram_en : out std_logic; + o_bram_we : out std_logic_vector(3 downto 0); -- Global Clock Signal - S_AXI_ACLK : in std_logic; + S_AXI_ACLK : in std_logic; -- Global Reset Signal. This Signal is Active LOW - S_AXI_ARESETN : in std_logic; + S_AXI_ARESETN : in std_logic; -- Write Address ID - S_AXI_AWID : in std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0); + S_AXI_AWID : in std_logic_vector(C_S_AXI_ID_WIDTH - 1 downto 0); -- Write address - S_AXI_AWADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0); + S_AXI_AWADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH - 1 downto 0); -- Burst length. The burst length gives the exact number of transfers in a burst - S_AXI_AWLEN : in std_logic_vector(7 downto 0); + S_AXI_AWLEN : in std_logic_vector(7 downto 0); -- Burst size. This signal indicates the size of each transfer in the burst - S_AXI_AWSIZE : in std_logic_vector(2 downto 0); + S_AXI_AWSIZE : in std_logic_vector(2 downto 0); -- Burst type. The burst type and the size information, -- determine how the address for each transfer within the burst is calculated. - S_AXI_AWBURST : in std_logic_vector(1 downto 0); + S_AXI_AWBURST : in std_logic_vector(1 downto 0); -- Lock type. Provides additional information about the -- atomic characteristics of the transfer. - S_AXI_AWLOCK : in std_logic; + S_AXI_AWLOCK : in std_logic; -- Memory type. This signal indicates how transactions -- are required to progress through a system. - S_AXI_AWCACHE : in std_logic_vector(3 downto 0); + S_AXI_AWCACHE : in std_logic_vector(3 downto 0); -- Protection type. This signal indicates the privilege -- and security level of the transaction, and whether -- the transaction is a data access or an instruction access. - S_AXI_AWPROT : in std_logic_vector(2 downto 0); + S_AXI_AWPROT : in std_logic_vector(2 downto 0); -- Quality of Service, QoS identifier sent for each -- write transaction. - S_AXI_AWQOS : in std_logic_vector(3 downto 0); + S_AXI_AWQOS : in std_logic_vector(3 downto 0); -- Region identifier. Permits a single physical interface -- on a slave to be used for multiple logical interfaces. - S_AXI_AWREGION : in std_logic_vector(3 downto 0); + S_AXI_AWREGION : in std_logic_vector(3 downto 0); -- Optional User-defined signal in the write address channel. --**S_AXI_AWUSER : in std_logic_vector(C_S_AXI_AWUSER_WIDTH-1 downto 0); @@ -83,92 +104,92 @@ entity scalp_hl2_S01_AXI is -- Write address valid. This signal indicates that -- the channel is signaling valid write address and -- control information. - S_AXI_AWVALID : in std_logic; + S_AXI_AWVALID : in std_logic; -- Write address ready. This signal indicates that -- the slave is ready to accept an address and associated -- control signals. - S_AXI_AWREADY : out std_logic; + S_AXI_AWREADY : out std_logic; -- Write Data - S_AXI_WDATA : in std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); + S_AXI_WDATA : in std_logic_vector(C_S_AXI_DATA_WIDTH - 1 downto 0); -- Write strobes. This signal indicates which byte -- lanes hold valid data. There is one write strobe -- bit for each eight bits of the write data bus. - S_AXI_WSTRB : in std_logic_vector((C_S_AXI_DATA_WIDTH/8)-1 downto 0); + S_AXI_WSTRB : in std_logic_vector((C_S_AXI_DATA_WIDTH/8) - 1 downto 0); -- Write last. This signal indicates the last transfer -- in a write burst. - S_AXI_WLAST : in std_logic; + S_AXI_WLAST : in std_logic; -- Optional User-defined signal in the write data channel. --**S_AXI_WUSER : in std_logic_vector(C_S_AXI_WUSER_WIDTH-1 downto 0); -- Write valid. This signal indicates that valid write -- data and strobes are available. - S_AXI_WVALID : in std_logic; + S_AXI_WVALID : in std_logic; -- Write ready. This signal indicates that the slave -- can accept the write data. - S_AXI_WREADY : out std_logic; + S_AXI_WREADY : out std_logic; -- Response ID tag. This signal is the ID tag of the -- write response. - S_AXI_BID : out std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0); + S_AXI_BID : out std_logic_vector(C_S_AXI_ID_WIDTH - 1 downto 0); -- Write response. This signal indicates the status -- of the write transaction. - S_AXI_BRESP : out std_logic_vector(1 downto 0); + S_AXI_BRESP : out std_logic_vector(1 downto 0); -- Optional User-defined signal in the write response channel. --** S_AXI_BUSER : out std_logic_vector(C_S_AXI_BUSER_WIDTH-1 downto 0); -- Write response valid. This signal indicates that the -- channel is signaling a valid write response. - S_AXI_BVALID : out std_logic; + S_AXI_BVALID : out std_logic; -- Response ready. This signal indicates that the master -- can accept a write response. - S_AXI_BREADY : in std_logic; + S_AXI_BREADY : in std_logic; -- Read address ID. This signal is the identification -- tag for the read address group of signals. - S_AXI_ARID : in std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0); + S_AXI_ARID : in std_logic_vector(C_S_AXI_ID_WIDTH - 1 downto 0); -- Read address. This signal indicates the initial -- address of a read burst transaction. - S_AXI_ARADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0); + S_AXI_ARADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH - 1 downto 0); -- Burst length. The burst length gives the exact number of transfers in a burst - S_AXI_ARLEN : in std_logic_vector(7 downto 0); + S_AXI_ARLEN : in std_logic_vector(7 downto 0); -- Burst size. This signal indicates the size of each transfer in the burst - S_AXI_ARSIZE : in std_logic_vector(2 downto 0); + S_AXI_ARSIZE : in std_logic_vector(2 downto 0); -- Burst type. The burst type and the size information, -- determine how the address for each transfer within the burst is calculated. - S_AXI_ARBURST : in std_logic_vector(1 downto 0); + S_AXI_ARBURST : in std_logic_vector(1 downto 0); -- Lock type. Provides additional information about the -- atomic characteristics of the transfer. - S_AXI_ARLOCK : in std_logic; + S_AXI_ARLOCK : in std_logic; -- Memory type. This signal indicates how transactions -- are required to progress through a system. - S_AXI_ARCACHE : in std_logic_vector(3 downto 0); + S_AXI_ARCACHE : in std_logic_vector(3 downto 0); -- Protection type. This signal indicates the privilege -- and security level of the transaction, and whether -- the transaction is a data access or an instruction access. - S_AXI_ARPROT : in std_logic_vector(2 downto 0); + S_AXI_ARPROT : in std_logic_vector(2 downto 0); -- Quality of Service, QoS identifier sent for each -- read transaction. - S_AXI_ARQOS : in std_logic_vector(3 downto 0); + S_AXI_ARQOS : in std_logic_vector(3 downto 0); -- Region identifier. Permits a single physical interface -- on a slave to be used for multiple logical interfaces. - S_AXI_ARREGION : in std_logic_vector(3 downto 0); + S_AXI_ARREGION : in std_logic_vector(3 downto 0); -- Optional User-defined signal in the read address channel. --**S_AXI_ARUSER : in std_logic_vector(C_S_AXI_ARUSER_WIDTH-1 downto 0); @@ -176,90 +197,90 @@ entity scalp_hl2_S01_AXI is -- Write address valid. This signal indicates that -- the channel is signaling valid read address and -- control information. - S_AXI_ARVALID : in std_logic; + S_AXI_ARVALID : in std_logic; -- Read address ready. This signal indicates that -- the slave is ready to accept an address and associated -- control signals. - S_AXI_ARREADY : out std_logic; + S_AXI_ARREADY : out std_logic; -- Read ID tag. This signal is the identification tag -- for the read data group of signals generated by the slave. - S_AXI_RID : out std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0); + S_AXI_RID : out std_logic_vector(C_S_AXI_ID_WIDTH - 1 downto 0); -- Read Data - S_AXI_RDATA : out std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); + S_AXI_RDATA : out std_logic_vector(C_S_AXI_DATA_WIDTH - 1 downto 0); -- Read response. This signal indicates the status of -- the read transfer. - S_AXI_RRESP : out std_logic_vector(1 downto 0); + S_AXI_RRESP : out std_logic_vector(1 downto 0); -- Read last. This signal indicates the last transfer -- in a read burst. - S_AXI_RLAST : out std_logic; + S_AXI_RLAST : out std_logic; -- Optional User-defined signal in the read address channel. --** S_AXI_RUSER : out std_logic_vector(C_S_AXI_RUSER_WIDTH-1 downto 0); -- Read valid. This signal indicates that the channel -- is signaling the required read data. - S_AXI_RVALID : out std_logic; + S_AXI_RVALID : out std_logic; -- Read ready. This signal indicates that the master can -- accept the read data and response information. - S_AXI_RREADY : in std_logic + S_AXI_RREADY : in std_logic ); end scalp_hl2_S01_AXI; architecture arch_imp of scalp_hl2_S01_AXI is -- AXI4FULL signals - signal axi_awaddr : std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0); - signal axi_awready : std_logic; - signal axi_wready : std_logic; - signal axi_bresp : std_logic_vector(1 downto 0); - signal axi_buser : std_logic_vector(C_S_AXI_BUSER_WIDTH-1 downto 0); - signal axi_bvalid : std_logic; - signal axi_araddr : std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0); - signal axi_arready : std_logic; - signal axi_rdata : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); - signal axi_rresp : std_logic_vector(1 downto 0); - signal axi_rlast : std_logic; - signal axi_ruser : std_logic_vector(C_S_AXI_RUSER_WIDTH-1 downto 0); - signal axi_rvalid : std_logic; + signal axi_awaddr : std_logic_vector(C_S_AXI_ADDR_WIDTH - 1 downto 0); + signal axi_awready : std_logic; + signal axi_wready : std_logic; + signal axi_bresp : std_logic_vector(1 downto 0); + signal axi_buser : std_logic_vector(C_S_AXI_BUSER_WIDTH - 1 downto 0); + signal axi_bvalid : std_logic; + signal axi_araddr : std_logic_vector(C_S_AXI_ADDR_WIDTH - 1 downto 0); + signal axi_arready : std_logic; + signal axi_rdata : std_logic_vector(C_S_AXI_DATA_WIDTH - 1 downto 0); + signal axi_rresp : std_logic_vector(1 downto 0); + signal axi_rlast : std_logic; + signal axi_ruser : std_logic_vector(C_S_AXI_RUSER_WIDTH - 1 downto 0); + signal axi_rvalid : std_logic; -- aw_wrap_en determines wrap boundary and enables wrapping - signal aw_wrap_en : std_logic; + signal aw_wrap_en : std_logic; -- ar_wrap_en determines wrap boundary and enables wrapping - signal ar_wrap_en : std_logic; + signal ar_wrap_en : std_logic; -- aw_wrap_size is the size of the write transfer, the -- write address wraps to a lower address if upper address -- limit is reached - signal aw_wrap_size : integer; + signal aw_wrap_size : integer; -- ar_wrap_size is the size of the read transfer, the -- read address wraps to a lower address if upper address -- limit is reached - signal ar_wrap_size : integer; + signal ar_wrap_size : integer; -- The axi_awv_awr_flag flag marks the presence of write address valid signal axi_awv_awr_flag : std_logic; --The axi_arv_arr_flag flag marks the presence of read address valid signal axi_arv_arr_flag : std_logic; -- The axi_awlen_cntr internal write address counter to keep track of beats in a burst transaction - signal axi_awlen_cntr : std_logic_vector(7 downto 0); + signal axi_awlen_cntr : std_logic_vector(7 downto 0); --The axi_arlen_cntr internal read address counter to keep track of beats in a burst transaction - signal axi_arlen_cntr : std_logic_vector(7 downto 0); - signal axi_arburst : std_logic_vector(2-1 downto 0); - signal axi_awburst : std_logic_vector(2-1 downto 0); - signal axi_arlen : std_logic_vector(8-1 downto 0); - signal axi_awlen : std_logic_vector(8-1 downto 0); + signal axi_arlen_cntr : std_logic_vector(7 downto 0); + signal axi_arburst : std_logic_vector(2 - 1 downto 0); + signal axi_awburst : std_logic_vector(2 - 1 downto 0); + signal axi_arlen : std_logic_vector(8 - 1 downto 0); + signal axi_awlen : std_logic_vector(8 - 1 downto 0); --local parameter for addressing 32 bit / 64 bit C_S_AXI_DATA_WIDTH --ADDR_LSB is used for addressing 32/64 bit registers/memories --ADDR_LSB = 2 for 32 bits (n downto 2) --ADDR_LSB = 3 for 42 bits (n downto 3) - constant ADDR_LSB : integer := (C_S_AXI_DATA_WIDTH/32)+ 1; - constant OPT_MEM_ADDR_BITS : integer := 16; - constant USER_NUM_MEM : integer := 1; - constant low : std_logic_vector (C_S_AXI_ADDR_WIDTH - 1 downto 0) := (others => '0'); + constant ADDR_LSB : integer := (C_S_AXI_DATA_WIDTH/32) + 1; + constant OPT_MEM_ADDR_BITS : integer := 16; + constant USER_NUM_MEM : integer := 1; + constant low : std_logic_vector (C_S_AXI_ADDR_WIDTH - 1 downto 0) := (others => '0'); type bram_read_state_t is ( S_IDLE, @@ -272,23 +293,25 @@ architecture arch_imp of scalp_hl2_S01_AXI is begin -- I/O Connections assignments - S_AXI_AWREADY <= axi_awready; - S_AXI_WREADY <= axi_wready; - S_AXI_BRESP <= axi_bresp; + S_AXI_AWREADY <= axi_awready; + S_AXI_WREADY <= axi_wready; + S_AXI_BRESP <= axi_bresp; --**S_AXI_BUSER <= axi_buser; - S_AXI_BVALID <= axi_bvalid; - S_AXI_ARREADY <= axi_arready; - S_AXI_RDATA <= axi_rdata; - S_AXI_RRESP <= axi_rresp; - S_AXI_RLAST <= axi_rlast; + S_AXI_BVALID <= axi_bvalid; + S_AXI_ARREADY <= axi_arready; + S_AXI_RDATA <= axi_rdata; + S_AXI_RRESP <= axi_rresp; + S_AXI_RLAST <= axi_rlast; --**S_AXI_RUSER <= axi_ruser; - S_AXI_RVALID <= axi_rvalid; - S_AXI_BID <= S_AXI_AWID; - S_AXI_RID <= S_AXI_ARID; - aw_wrap_size <= ((C_S_AXI_DATA_WIDTH)/8 * to_integer(unsigned(axi_awlen))); - ar_wrap_size <= ((C_S_AXI_DATA_WIDTH)/8 * to_integer(unsigned(axi_arlen))); - aw_wrap_en <= '1' when (((axi_awaddr AND std_logic_vector(to_unsigned(aw_wrap_size,C_S_AXI_ADDR_WIDTH))) XOR std_logic_vector(to_unsigned(aw_wrap_size,C_S_AXI_ADDR_WIDTH))) = low) else '0'; - ar_wrap_en <= '1' when (((axi_araddr AND std_logic_vector(to_unsigned(ar_wrap_size,C_S_AXI_ADDR_WIDTH))) XOR std_logic_vector(to_unsigned(ar_wrap_size,C_S_AXI_ADDR_WIDTH))) = low) else '0'; + S_AXI_RVALID <= axi_rvalid; + S_AXI_BID <= S_AXI_AWID; + S_AXI_RID <= S_AXI_ARID; + aw_wrap_size <= ((C_S_AXI_DATA_WIDTH)/8 * to_integer(unsigned(axi_awlen))); + ar_wrap_size <= ((C_S_AXI_DATA_WIDTH)/8 * to_integer(unsigned(axi_arlen))); + aw_wrap_en <= '1' when (((axi_awaddr and std_logic_vector(to_unsigned(aw_wrap_size, C_S_AXI_ADDR_WIDTH))) xor std_logic_vector(to_unsigned(aw_wrap_size, C_S_AXI_ADDR_WIDTH))) = low) else + '0'; + ar_wrap_en <= '1' when (((axi_araddr and std_logic_vector(to_unsigned(ar_wrap_size, C_S_AXI_ADDR_WIDTH))) xor std_logic_vector(to_unsigned(ar_wrap_size, C_S_AXI_ADDR_WIDTH))) = low) else + '0'; --------------------------------------------------------------------------- -- Implement axi_awready generation @@ -299,24 +322,24 @@ begin process (S_AXI_ACLK) begin - if rising_edge(S_AXI_ACLK) then - if S_AXI_ARESETN = '0' then - axi_awready <= '0'; - axi_awv_awr_flag <= '0'; - else - if (axi_awready = '0' and S_AXI_AWVALID = '1' and axi_awv_awr_flag = '0' and axi_arv_arr_flag = '0') then - -- slave is ready to accept an address and - -- associated control signals - axi_awv_awr_flag <= '1'; -- used for generation of bresp() and bvalid - axi_awready <= '1'; - elsif (S_AXI_WLAST = '1' and axi_wready = '1') then - -- preparing to accept next address after current write burst tx completion - axi_awv_awr_flag <= '0'; - else - axi_awready <= '0'; - end if; + if rising_edge(S_AXI_ACLK) then + if S_AXI_ARESETN = '0' then + axi_awready <= '0'; + axi_awv_awr_flag <= '0'; + else + if (axi_awready = '0' and S_AXI_AWVALID = '1' and axi_awv_awr_flag = '0' and axi_arv_arr_flag = '0') then + -- slave is ready to accept an address and + -- associated control signals + axi_awv_awr_flag <= '1'; -- used for generation of bresp() and bvalid + axi_awready <= '1'; + elsif (S_AXI_WLAST = '1' and axi_wready = '1') then + -- preparing to accept next address after current write burst tx completion + axi_awv_awr_flag <= '0'; + else + axi_awready <= '0'; + end if; + end if; end if; - end if; end process; --------------------------------------------------------------------------- @@ -327,45 +350,45 @@ begin process (S_AXI_ACLK) begin - if rising_edge(S_AXI_ACLK) then - if S_AXI_ARESETN = '0' then - axi_awaddr <= (others => '0'); - axi_awburst <= (others => '0'); - axi_awlen <= (others => '0'); - axi_awlen_cntr <= (others => '0'); - else - if (axi_awready = '0' and S_AXI_AWVALID = '1' and axi_awv_awr_flag = '0') then - -- address latching - axi_awaddr <= S_AXI_AWADDR(C_S_AXI_ADDR_WIDTH - 1 downto 0); ---- start address of transfer - axi_awlen_cntr <= (others => '0'); - axi_awburst <= S_AXI_AWBURST; - axi_awlen <= S_AXI_AWLEN; - elsif((axi_awlen_cntr <= axi_awlen) and axi_wready = '1' and S_AXI_WVALID = '1') then - axi_awlen_cntr <= std_logic_vector (unsigned(axi_awlen_cntr) + 1); - - case (axi_awburst) is - when "00" => -- fixed burst - -- The write address for all the beats in the transaction are fixed - axi_awaddr <= axi_awaddr; ----for awsize = 4 bytes (010) - when "01" => --incremental burst - -- The write address for all the beats in the transaction are increments by awsize - axi_awaddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB) <= std_logic_vector (unsigned(axi_awaddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB)) + 1);--awaddr aligned to 4 byte boundary - axi_awaddr(ADDR_LSB-1 downto 0) <= (others => '0'); ----for awsize = 4 bytes (010) - when "10" => --Wrapping burst - -- The write address wraps when the address reaches wrap boundary - if (aw_wrap_en = '1') then - axi_awaddr <= std_logic_vector (unsigned(axi_awaddr) - (to_unsigned(aw_wrap_size,C_S_AXI_ADDR_WIDTH))); - else - axi_awaddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB) <= std_logic_vector (unsigned(axi_awaddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB)) + 1);--awaddr aligned to 4 byte boundary - axi_awaddr(ADDR_LSB-1 downto 0) <= (others => '0'); ----for awsize = 4 bytes (010) + if rising_edge(S_AXI_ACLK) then + if S_AXI_ARESETN = '0' then + axi_awaddr <= (others => '0'); + axi_awburst <= (others => '0'); + axi_awlen <= (others => '0'); + axi_awlen_cntr <= (others => '0'); + else + if (axi_awready = '0' and S_AXI_AWVALID = '1' and axi_awv_awr_flag = '0') then + -- address latching + axi_awaddr <= S_AXI_AWADDR(C_S_AXI_ADDR_WIDTH - 1 downto 0); ---- start address of transfer + axi_awlen_cntr <= (others => '0'); + axi_awburst <= S_AXI_AWBURST; + axi_awlen <= S_AXI_AWLEN; + elsif ((axi_awlen_cntr <= axi_awlen) and axi_wready = '1' and S_AXI_WVALID = '1') then + axi_awlen_cntr <= std_logic_vector (unsigned(axi_awlen_cntr) + 1); + + case (axi_awburst) is + when "00" => -- fixed burst + -- The write address for all the beats in the transaction are fixed + axi_awaddr <= axi_awaddr; ----for awsize = 4 bytes (010) + when "01" => --incremental burst + -- The write address for all the beats in the transaction are increments by awsize + axi_awaddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB) <= std_logic_vector (unsigned(axi_awaddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB)) + 1);--awaddr aligned to 4 byte boundary + axi_awaddr(ADDR_LSB - 1 downto 0) <= (others => '0'); ----for awsize = 4 bytes (010) + when "10" => --Wrapping burst + -- The write address wraps when the address reaches wrap boundary + if (aw_wrap_en = '1') then + axi_awaddr <= std_logic_vector (unsigned(axi_awaddr) - (to_unsigned(aw_wrap_size, C_S_AXI_ADDR_WIDTH))); + else + axi_awaddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB) <= std_logic_vector (unsigned(axi_awaddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB)) + 1);--awaddr aligned to 4 byte boundary + axi_awaddr(ADDR_LSB - 1 downto 0) <= (others => '0'); ----for awsize = 4 bytes (010) + end if; + when others => --reserved (incremental burst for example) + axi_awaddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB) <= std_logic_vector (unsigned(axi_awaddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB)) + 1);--for awsize = 4 bytes (010) + axi_awaddr(ADDR_LSB - 1 downto 0) <= (others => '0'); + end case; end if; - when others => --reserved (incremental burst for example) - axi_awaddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB) <= std_logic_vector (unsigned(axi_awaddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB)) + 1);--for awsize = 4 bytes (010) - axi_awaddr(ADDR_LSB-1 downto 0) <= (others => '0'); - end case; - end if; + end if; end if; - end if; end process; --------------------------------------------------------------------------- @@ -377,19 +400,19 @@ begin process (S_AXI_ACLK) begin - if rising_edge(S_AXI_ACLK) then - if S_AXI_ARESETN = '0' then - axi_wready <= '0'; - else - if (axi_wready = '0' and S_AXI_WVALID = '1' and axi_awv_awr_flag = '1') then - axi_wready <= '1'; - -- elsif (axi_awv_awr_flag = '0') then - elsif (S_AXI_WLAST = '1' and axi_wready = '1') then - - axi_wready <= '0'; - end if; + if rising_edge(S_AXI_ACLK) then + if S_AXI_ARESETN = '0' then + axi_wready <= '0'; + else + if (axi_wready = '0' and S_AXI_WVALID = '1' and axi_awv_awr_flag = '1') then + axi_wready <= '1'; + -- elsif (axi_awv_awr_flag = '0') then + elsif (S_AXI_WLAST = '1' and axi_wready = '1') then + + axi_wready <= '0'; + end if; + end if; end if; - end if; end process; --------------------------------------------------------------------------- @@ -402,21 +425,21 @@ begin process (S_AXI_ACLK) begin - if rising_edge(S_AXI_ACLK) then - if S_AXI_ARESETN = '0' then - axi_bvalid <= '0'; - axi_bresp <= "00"; --need to work more on the responses - axi_buser <= (others => '0'); - else - if (axi_awv_awr_flag = '1' and axi_wready = '1' and S_AXI_WVALID = '1' and axi_bvalid = '0' and S_AXI_WLAST = '1' ) then - axi_bvalid <= '1'; - axi_bresp <= "00"; - elsif (S_AXI_BREADY = '1' and axi_bvalid = '1') then - --check if bready is asserted while bvalid is high) - axi_bvalid <= '0'; - end if; + if rising_edge(S_AXI_ACLK) then + if S_AXI_ARESETN = '0' then + axi_bvalid <= '0'; + axi_bresp <= "00"; --need to work more on the responses + axi_buser <= (others => '0'); + else + if (axi_awv_awr_flag = '1' and axi_wready = '1' and S_AXI_WVALID = '1' and axi_bvalid = '0' and S_AXI_WLAST = '1') then + axi_bvalid <= '1'; + axi_bresp <= "00"; + elsif (S_AXI_BREADY = '1' and axi_bvalid = '1') then + --check if bready is asserted while bvalid is high) + axi_bvalid <= '0'; + end if; + end if; end if; - end if; end process; --------------------------------------------------------------------------- @@ -430,22 +453,22 @@ begin process (S_AXI_ACLK) begin - if rising_edge(S_AXI_ACLK) then - if S_AXI_ARESETN = '0' then - axi_arready <= '0'; - axi_arv_arr_flag <= '0'; - else - if (axi_arready = '0' and S_AXI_ARVALID = '1' and axi_awv_awr_flag = '0' and axi_arv_arr_flag = '0') then - axi_arready <= '1'; - axi_arv_arr_flag <= '1'; - elsif (axi_rvalid = '1' and S_AXI_RREADY = '1' and (axi_arlen_cntr = axi_arlen)) then - -- preparing to accept next address after current read completion - axi_arv_arr_flag <= '0'; - else - axi_arready <= '0'; - end if; + if rising_edge(S_AXI_ACLK) then + if S_AXI_ARESETN = '0' then + axi_arready <= '0'; + axi_arv_arr_flag <= '0'; + else + if (axi_arready = '0' and S_AXI_ARVALID = '1' and axi_awv_awr_flag = '0' and axi_arv_arr_flag = '0') then + axi_arready <= '1'; + axi_arv_arr_flag <= '1'; + elsif (axi_rvalid = '1' and S_AXI_RREADY = '1' and (axi_arlen_cntr = axi_arlen)) then + -- preparing to accept next address after current read completion + axi_arv_arr_flag <= '0'; + else + axi_arready <= '0'; + end if; + end if; end if; - end if; end process; --------------------------------------------------------------------------- @@ -456,54 +479,54 @@ begin process (S_AXI_ACLK) begin - if rising_edge(S_AXI_ACLK) then - if S_AXI_ARESETN = '0' then - axi_araddr <= (others => '0'); - axi_arburst <= (others => '0'); - axi_arlen <= (others => '0'); - axi_arlen_cntr <= (others => '0'); - axi_rlast <= '0'; - axi_ruser <= (others => '0'); - else - if (axi_arready = '0' and S_AXI_ARVALID = '1' and axi_arv_arr_flag = '0') then - -- address latching - axi_araddr <= S_AXI_ARADDR(C_S_AXI_ADDR_WIDTH - 1 downto 0); ---- start address of transfer - axi_arlen_cntr <= (others => '0'); - axi_rlast <= '0'; - axi_arburst <= S_AXI_ARBURST; - axi_arlen <= S_AXI_ARLEN; - elsif((axi_arlen_cntr <= axi_arlen) and axi_rvalid = '1' and S_AXI_RREADY = '1') then - axi_arlen_cntr <= std_logic_vector (unsigned(axi_arlen_cntr) + 1); - axi_rlast <= '0'; - - case (axi_arburst) is - when "00" => -- fixed burst - -- The read address for all the beats in the transaction are fixed - axi_araddr <= axi_araddr; ----for arsize = 4 bytes (010) - when "01" => --incremental burst - -- The read address for all the beats in the transaction are increments by awsize - axi_araddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB) <= std_logic_vector (unsigned(axi_araddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB)) + 1); --araddr aligned to 4 byte boundary - axi_araddr(ADDR_LSB-1 downto 0) <= (others => '0'); ----for awsize = 4 bytes (010) - when "10" => --Wrapping burst - -- The read address wraps when the address reaches wrap boundary - if (ar_wrap_en = '1') then - axi_araddr <= std_logic_vector (unsigned(axi_araddr) - (to_unsigned(ar_wrap_size,C_S_AXI_ADDR_WIDTH))); - else - axi_araddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB) <= std_logic_vector (unsigned(axi_araddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB)) + 1); --araddr aligned to 4 byte boundary - axi_araddr(ADDR_LSB-1 downto 0) <= (others => '0'); ----for awsize = 4 bytes (010) + if rising_edge(S_AXI_ACLK) then + if S_AXI_ARESETN = '0' then + axi_araddr <= (others => '0'); + axi_arburst <= (others => '0'); + axi_arlen <= (others => '0'); + axi_arlen_cntr <= (others => '0'); + axi_rlast <= '0'; + axi_ruser <= (others => '0'); + else + if (axi_arready = '0' and S_AXI_ARVALID = '1' and axi_arv_arr_flag = '0') then + -- address latching + axi_araddr <= S_AXI_ARADDR(C_S_AXI_ADDR_WIDTH - 1 downto 0); ---- start address of transfer + axi_arlen_cntr <= (others => '0'); + axi_rlast <= '0'; + axi_arburst <= S_AXI_ARBURST; + axi_arlen <= S_AXI_ARLEN; + elsif ((axi_arlen_cntr <= axi_arlen) and axi_rvalid = '1' and S_AXI_RREADY = '1') then + axi_arlen_cntr <= std_logic_vector (unsigned(axi_arlen_cntr) + 1); + axi_rlast <= '0'; + + case (axi_arburst) is + when "00" => -- fixed burst + -- The read address for all the beats in the transaction are fixed + axi_araddr <= axi_araddr; ----for arsize = 4 bytes (010) + when "01" => --incremental burst + -- The read address for all the beats in the transaction are increments by awsize + axi_araddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB) <= std_logic_vector (unsigned(axi_araddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB)) + 1); --araddr aligned to 4 byte boundary + axi_araddr(ADDR_LSB - 1 downto 0) <= (others => '0'); ----for awsize = 4 bytes (010) + when "10" => --Wrapping burst + -- The read address wraps when the address reaches wrap boundary + if (ar_wrap_en = '1') then + axi_araddr <= std_logic_vector (unsigned(axi_araddr) - (to_unsigned(ar_wrap_size, C_S_AXI_ADDR_WIDTH))); + else + axi_araddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB) <= std_logic_vector (unsigned(axi_araddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB)) + 1); --araddr aligned to 4 byte boundary + axi_araddr(ADDR_LSB - 1 downto 0) <= (others => '0'); ----for awsize = 4 bytes (010) + end if; + when others => --reserved (incremental burst for example) + axi_araddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB) <= std_logic_vector (unsigned(axi_araddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB)) + 1);--for arsize = 4 bytes (010) + axi_araddr(ADDR_LSB - 1 downto 0) <= (others => '0'); + end case; + elsif ((axi_arlen_cntr = axi_arlen) and axi_rlast = '0' and axi_arv_arr_flag = '1') then + axi_rlast <= '1'; + elsif (S_AXI_RREADY = '1') and axi_rvalid = '1' then + axi_rlast <= '0'; end if; - when others => --reserved (incremental burst for example) - axi_araddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB) <= std_logic_vector (unsigned(axi_araddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB)) + 1);--for arsize = 4 bytes (010) - axi_araddr(ADDR_LSB-1 downto 0) <= (others => '0'); - end case; - elsif((axi_arlen_cntr = axi_arlen) and axi_rlast = '0' and axi_arv_arr_flag = '1') then - axi_rlast <= '1'; - elsif (S_AXI_RREADY = '1') and axi_rvalid = '1' then - axi_rlast <= '0'; - end if; + end if; end if; - end if; - end process; + end process; --------------------------------------------------------------------------- -- Implement axi_rvalid generation @@ -535,45 +558,45 @@ begin process (S_AXI_ACLK) begin - if rising_edge(S_AXI_ACLK) then - if S_AXI_ARESETN = '0' then - axi_rvalid <= '0'; - axi_rresp <= "00"; - bram_read_state <= S_IDLE; - else - case bram_read_state is - when S_IDLE => - axi_rvalid <= '0'; - axi_rresp <= "00"; - if (axi_arready = '1' and S_AXI_ARVALID = '1') then - bram_read_state <= S_FETCH2; - else - bram_read_state <= S_IDLE; - end if; - when S_FETCH1 => - axi_rvalid <= '0'; - axi_rresp <= "00"; - bram_read_state <= S_FETCH2; - when S_FETCH2 => - axi_rvalid <= '1'; - axi_rresp <= "00"; - bram_read_state <= S_VALID; - when S_VALID => - if S_AXI_RREADY = '1' then + if rising_edge(S_AXI_ACLK) then + if S_AXI_ARESETN = '0' then + axi_rvalid <= '0'; + axi_rresp <= "00"; + bram_read_state <= S_IDLE; + else + case bram_read_state is + when S_IDLE => axi_rvalid <= '0'; - if axi_rlast = '0' then - bram_read_state <= S_FETCH1; + axi_rresp <= "00"; + if (axi_arready = '1' and S_AXI_ARVALID = '1') then + bram_read_state <= S_FETCH2; else bram_read_state <= S_IDLE; end if; - else - axi_rvalid <= '1'; + when S_FETCH1 => + axi_rvalid <= '0'; + axi_rresp <= "00"; + bram_read_state <= S_FETCH2; + when S_FETCH2 => + axi_rvalid <= '1'; + axi_rresp <= "00"; bram_read_state <= S_VALID; - end if; - end case; + when S_VALID => + if S_AXI_RREADY = '1' then + axi_rvalid <= '0'; + if axi_rlast = '0' then + bram_read_state <= S_FETCH1; + else + bram_read_state <= S_IDLE; + end if; + else + axi_rvalid <= '1'; + bram_read_state <= S_VALID; + end if; + end case; + end if; end if; - end if; - end process; + end process; --------------------------------------------------------------------------- -- Generate BRAM access signals @@ -581,12 +604,14 @@ begin o_bram_en <= axi_wready or axi_arv_arr_flag; -- Set bram address only during axi transactions - o_bram_addr <= axi_araddr(ADDR_LSB+OPT_MEM_ADDR_BITS downto ADDR_LSB) when axi_arv_arr_flag = '1' else - axi_awaddr(ADDR_LSB+OPT_MEM_ADDR_BITS downto ADDR_LSB) when axi_awv_awr_flag = '1' else - (others => '0'); + o_bram_addr <= axi_araddr(ADDR_LSB + OPT_MEM_ADDR_BITS downto ADDR_LSB) when axi_arv_arr_flag = '1' else + axi_awaddr(ADDR_LSB + OPT_MEM_ADDR_BITS downto ADDR_LSB) when axi_awv_awr_flag = '1' else + (others => '0'); o_bram_wdata <= S_AXI_WDATA; - o_bram_we <= S_AXI_WSTRB when S_AXI_ARESETN = '1' and axi_wready = '1' else (others => '0'); - axi_rdata <= i_bram_rdata when axi_rvalid = '1' else (others => '0'); + o_bram_we <= S_AXI_WSTRB when S_AXI_ARESETN = '1' and axi_wready = '1' else + (others => '0'); + axi_rdata <= i_bram_rdata when axi_rvalid = '1' else + (others => '0'); -end arch_imp; +end arch_imp; \ No newline at end of file diff --git a/ips/hw/scalp_hl2/src/hdl/scalp_hl2_bram.vhd b/ips/hw/scalp_hl2/src/hdl/scalp_hl2_bram.vhd index b427da9..f2f5ed7 100755 --- a/ips/hw/scalp_hl2/src/hdl/scalp_hl2_bram.vhd +++ b/ips/hw/scalp_hl2/src/hdl/scalp_hl2_bram.vhd @@ -1,67 +1,88 @@ +---------------------------------------------------------------------------------- +-- _ _ +-- | |_ ___ _ __(_)__ _ +-- | ' \/ -_) '_ \ / _` | +-- |_||_\___| .__/_\__,_| +-- |_| +-- +---------------------------------------------------------------------------------- +-- +-- Company: hepia +-- Author: Quentin Berthet <quentin.berthet@hesge.ch +-- +-- Module Name: scalp_hl2_bram +-- Target Device: hepia-cores.ch:scalp_node:part0:0.1 xc7z015clg485-2 +-- Tool version: 2019.2 +-- Description: Instanciates simple dual port BRAM bank generic in size. +-- +-- Last update: 2020/12/17 12:09:55 +-- +--------------------------------------------------------------------------------- + library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; -Library xpm; +library xpm; use xpm.vcomponents.all; library xil_defaultlib; use xil_defaultlib.scalp_hl2_pkg.all; entity scalp_hl2_bram is - generic ( - G_PORT_COUNT : integer := 1 - ); - port ( - i_clk : in std_logic; - i_nrst : in std_logic; - - -- AXI Ports Data bus - o_axi_data : out std_logic_vector(31 downto 0); - i_axi_addr : in std_logic_vector(16 downto 0); - i_axi_data : in std_logic_vector(31 downto 0); - i_axi_en : in std_logic; - i_axi_we : in std_logic_vector(3 downto 0); - - -- DMX Ports Data bus - o_dmx_data : out std_logic_vector((8*G_PORT_COUNT)-1 downto 0); - i_dmx_addr : in std_logic_vector(C_REG_CHAN_COUNT_SIZE-1 downto 0); - i_dmx_rden : in std_logic - ); + generic ( + G_PORT_COUNT : integer := 1 + ); + port ( + i_clk : in std_logic; + i_nrst : in std_logic; + + -- AXI Ports Data bus + o_axi_data : out std_logic_vector(31 downto 0); + i_axi_addr : in std_logic_vector(16 downto 0); + i_axi_data : in std_logic_vector(31 downto 0); + i_axi_en : in std_logic; + i_axi_we : in std_logic_vector(3 downto 0); + + -- DMX Ports Data bus + o_dmx_data : out std_logic_vector((8 * G_PORT_COUNT) - 1 downto 0); + i_dmx_addr : in std_logic_vector(C_REG_CHAN_COUNT_SIZE - 1 downto 0); + i_dmx_rden : in std_logic + ); end scalp_hl2_bram; architecture RTL of scalp_hl2_bram is -COMPONENT blk_mem_gen_0 - PORT ( - clka : IN STD_LOGIC; - rsta : IN STD_LOGIC; - ena : IN STD_LOGIC; - wea : IN STD_LOGIC_VECTOR(3 DOWNTO 0); - addra : IN STD_LOGIC_VECTOR(9 DOWNTO 0); - dina : IN STD_LOGIC_VECTOR(31 DOWNTO 0); - douta : OUT STD_LOGIC_VECTOR(31 DOWNTO 0); - clkb : IN STD_LOGIC; - rstb : IN STD_LOGIC; - enb : IN STD_LOGIC; - web : IN STD_LOGIC_VECTOR(0 DOWNTO 0); - addrb : IN STD_LOGIC_VECTOR(11 DOWNTO 0); - dinb : IN STD_LOGIC_VECTOR(7 DOWNTO 0); - doutb : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); - rsta_busy : OUT STD_LOGIC; - rstb_busy : OUT STD_LOGIC - ); -END COMPONENT; - - signal s_rst : std_logic; - - signal s_bram_sel : std_logic_vector(6 downto 0); - signal s_bram_addr : std_logic_vector(9 downto 0); - - signal s_en : std_logic; - signal s_bram_en : std_logic_vector(G_PORT_COUNT-1 downto 0); - - type s_axi_data_out_t is array (0 to G_PORT_COUNT-1) of std_logic_vector(31 downto 0); + component blk_mem_gen_0 + port ( + clka : in std_logic; + rsta : in std_logic; + ena : in std_logic; + wea : in std_logic_vector(3 downto 0); + addra : in std_logic_vector(9 downto 0); + dina : in std_logic_vector(31 downto 0); + douta : out std_logic_vector(31 downto 0); + clkb : in std_logic; + rstb : in std_logic; + enb : in std_logic; + web : in std_logic_vector(0 downto 0); + addrb : in std_logic_vector(11 downto 0); + dinb : in std_logic_vector(7 downto 0); + doutb : out std_logic_vector(7 downto 0); + rsta_busy : out std_logic; + rstb_busy : out std_logic + ); + end component; + + signal s_rst : std_logic; + + signal s_bram_sel : std_logic_vector(6 downto 0); + signal s_bram_addr : std_logic_vector(9 downto 0); + + signal s_en : std_logic; + signal s_bram_en : std_logic_vector(G_PORT_COUNT - 1 downto 0); + + type s_axi_data_out_t is array (0 to G_PORT_COUNT - 1) of std_logic_vector(31 downto 0); signal s_axi_data_out : s_axi_data_out_t; begin @@ -72,19 +93,19 @@ begin -- Split AXI address into BRAM select and BRAM address s_bram_sel <= i_axi_addr(16 downto 10); s_bram_addr <= i_axi_addr(9 downto 0); - - s_en <= i_axi_en; + + s_en <= i_axi_en; -- Bram selection -- Alternate to test: - -- output <= (others => '0'); -- default - -- output(to_integer(input)) <= '1'; + -- output <= (others => '0'); -- default + -- output(to_integer(input)) <= '1'; BRAM_SEL : process (i_nrst, s_bram_sel, s_en) begin if i_nrst = '0' then s_bram_en <= (others => '0'); else - for i in 0 to G_PORT_COUNT-1 loop + for i in 0 to G_PORT_COUNT - 1 loop if i = to_integer(unsigned(s_bram_sel)) then s_bram_en(i) <= s_en; else @@ -101,28 +122,28 @@ begin end process DOUT_SEL; -- BRAM instances - RAM_GEN : for i in 0 to G_PORT_COUNT-1 generate + RAM_GEN : for i in 0 to G_PORT_COUNT - 1 generate begin blk_mem_gen_i : blk_mem_gen_0 - PORT MAP ( - clka => i_clk, - rsta => s_rst, - ena => s_bram_en(i), - wea => i_axi_we, - addra => s_bram_addr, - dina => i_axi_data, - douta => s_axi_data_out(i), - clkb => i_clk, - rstb => s_rst, - enb => i_dmx_rden, - web => "0", - addrb => i_dmx_addr, + port map( + clka => i_clk, + rsta => s_rst, + ena => s_bram_en(i), + wea => i_axi_we, + addra => s_bram_addr, + dina => i_axi_data, + douta => s_axi_data_out(i), + clkb => i_clk, + rstb => s_rst, + enb => i_dmx_rden, + web => "0", + addrb => i_dmx_addr, dinb => (others => '0'), - doutb => o_dmx_data(((i*8)+7) downto i*8), + doutb => o_dmx_data(((i * 8) + 7) downto i * 8), rsta_busy => open, rstb_busy => open - ); + ); end generate RAM_GEN; diff --git a/ips/hw/scalp_hl2/src/hdl/scalp_hl2_ctrl.vhd b/ips/hw/scalp_hl2/src/hdl/scalp_hl2_ctrl.vhd index f9c7756..28872bf 100755 --- a/ips/hw/scalp_hl2/src/hdl/scalp_hl2_ctrl.vhd +++ b/ips/hw/scalp_hl2/src/hdl/scalp_hl2_ctrl.vhd @@ -1,9 +1,30 @@ +---------------------------------------------------------------------------------- +-- _ _ +-- | |_ ___ _ __(_)__ _ +-- | ' \/ -_) '_ \ / _` | +-- |_||_\___| .__/_\__,_| +-- |_| +-- +---------------------------------------------------------------------------------- +-- +-- Company: hepia +-- Author: Quentin Berthet <quentin.berthet@hesge.ch +-- +-- Module Name: scalp_hl2_ctrl +-- Target Device: hepia-cores.ch:scalp_node:part0:0.1 xc7z015clg485-2 +-- Tool version: 2019.2 +-- Description: Implement serialization state-machine: DMX-512 protocol +-- +-- Last update: 2020/12/17 12:09:57 +-- +--------------------------------------------------------------------------------- + library IEEE; -use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_1164.all; -- Uncomment the following library declaration if using -- arithmetic functions with Signed or Unsigned values -use IEEE.NUMERIC_STD.ALL; +use IEEE.NUMERIC_STD.all; library xil_defaultlib; use xil_defaultlib.scalp_hl2_pkg.all; @@ -14,31 +35,31 @@ use xil_defaultlib.scalp_hl2_pkg.all; --use UNISIM.VComponents.all; entity scalp_hl2_ctrl is - generic ( - G_PORT_COUNT : integer := 1 - ); - port ( - i_clk : in std_logic; - i_nrst : in std_logic; - - -- Config registers - ir_mab_clk : in std_logic_vector(C_REG_MAB_CLK_SIZE-1 downto 0); - ir_break_clk : in std_logic_vector(C_REG_BREAK_CLK_SIZE-1 downto 0); - ir_bit_clk : in std_logic_vector(C_REG_BIT_CLK_SIZE-1 downto 0); - ir_chan_count : in std_logic_vector(C_REG_CHAN_COUNT_SIZE-1 downto 0); - ir_global_en : in std_logic_vector(C_REG_GLOBAL_EN_SIZE-1 downto 0); - ir_sof_value : in std_logic_vector((C_REG_SOF_VALUE_SIZE*G_PORT_COUNT)-1 downto 0); - ir_idl_value : in std_logic_vector((C_REG_IDL_SIZE*G_PORT_COUNT)-1 downto 0); - ir_chan_en : in std_logic_vector((C_REG_EN_SIZE*G_PORT_COUNT)-1 downto 0); - - -- Data bus - i_data : in std_logic_vector((8*G_PORT_COUNT)-1 downto 0); - o_addr : out std_logic_vector(C_REG_CHAN_COUNT_SIZE-1 downto 0); - o_rden : out std_logic; - - -- Dmx - o_dmx : out std_logic_vector(G_PORT_COUNT-1 downto 0) - ); + generic ( + G_PORT_COUNT : integer := 1 + ); + port ( + i_clk : in std_logic; + i_nrst : in std_logic; + + -- Config registers + ir_mab_clk : in std_logic_vector(C_REG_MAB_CLK_SIZE - 1 downto 0); + ir_break_clk : in std_logic_vector(C_REG_BREAK_CLK_SIZE - 1 downto 0); + ir_bit_clk : in std_logic_vector(C_REG_BIT_CLK_SIZE - 1 downto 0); + ir_chan_count : in std_logic_vector(C_REG_CHAN_COUNT_SIZE - 1 downto 0); + ir_global_en : in std_logic_vector(C_REG_GLOBAL_EN_SIZE - 1 downto 0); + ir_sof_value : in std_logic_vector((C_REG_SOF_VALUE_SIZE * G_PORT_COUNT) - 1 downto 0); + ir_idl_value : in std_logic_vector((C_REG_IDL_SIZE * G_PORT_COUNT) - 1 downto 0); + ir_chan_en : in std_logic_vector((C_REG_EN_SIZE * G_PORT_COUNT) - 1 downto 0); + + -- Data bus + i_data : in std_logic_vector((8 * G_PORT_COUNT) - 1 downto 0); + o_addr : out std_logic_vector(C_REG_CHAN_COUNT_SIZE - 1 downto 0); + o_rden : out std_logic; + + -- Dmx + o_dmx : out std_logic_vector(G_PORT_COUNT - 1 downto 0) + ); end scalp_hl2_ctrl; architecture Behavioral of scalp_hl2_ctrl is @@ -53,27 +74,27 @@ architecture Behavioral of scalp_hl2_ctrl is s_WaitDataFrame ); - signal r_SM_Main : t_SM_Main; + signal r_SM_Main : t_SM_Main; signal s_uart_done : std_logic; signal s_uart_strobe : std_logic; - signal s_uartdmx : std_logic_vector(G_PORT_COUNT-1 downto 0); - signal r_tx_data : std_logic_vector((G_PORT_COUNT*8)-1 downto 0); - signal r_Clk_Count : unsigned(C_REG_BREAK_CLK_SIZE-1 downto 0); - signal r_data_addr : unsigned(C_REG_CHAN_COUNT_SIZE-1 downto 0); + signal s_uartdmx : std_logic_vector(G_PORT_COUNT - 1 downto 0); + signal r_tx_data : std_logic_vector((G_PORT_COUNT * 8) - 1 downto 0); + signal r_Clk_Count : unsigned(C_REG_BREAK_CLK_SIZE - 1 downto 0); + signal r_data_addr : unsigned(C_REG_CHAN_COUNT_SIZE - 1 downto 0); component scalp_hl2_uart is - generic ( - G_PORT_COUNT : integer + generic ( + G_PORT_COUNT : integer ); - port ( - i_clk : in std_logic; - ir_bit_clk : in std_logic_vector(C_REG_BIT_CLK_SIZE-1 downto 0); - i_data_valid : in std_logic; - i_data : in std_logic_vector((8*G_PORT_COUNT)-1 downto 0); - o_active : out std_logic; - o_dmx : out std_logic_vector(G_PORT_COUNT-1 downto 0); - o_done : out std_logic + port ( + i_clk : in std_logic; + ir_bit_clk : in std_logic_vector(C_REG_BIT_CLK_SIZE - 1 downto 0); + i_data_valid : in std_logic; + i_data : in std_logic_vector((8 * G_PORT_COUNT) - 1 downto 0); + o_active : out std_logic; + o_dmx : out std_logic_vector(G_PORT_COUNT - 1 downto 0); + o_done : out std_logic ); end component scalp_hl2_uart; @@ -87,7 +108,7 @@ begin -- Init out line and counters r_Clk_Count <= (others => '0'); r_data_addr <= (others => '0'); - r_SM_Main <= s_Init; + r_SM_Main <= s_Init; else case r_SM_Main is when s_Init => @@ -95,57 +116,57 @@ begin r_Clk_Count <= (others => '0'); r_data_addr <= (others => '0'); -- go to s_Break - r_SM_Main <= s_Break; + r_SM_Main <= s_Break; when s_Break => -- Set out line low -- Done in the mux at the end of file - + -- wait ir_break_clk clock cycles if r_Clk_Count < unsigned(ir_break_clk) - 1 then - r_Clk_Count <= r_Clk_Count + 1; - r_SM_Main <= s_Break; + r_Clk_Count <= r_Clk_Count + 1; + r_SM_Main <= s_Break; else - r_Clk_Count <= (others => '0'); - r_SM_Main <= s_MarkAfterBreak; + r_Clk_Count <= (others => '0'); + r_SM_Main <= s_MarkAfterBreak; end if; - + -- go to s_MarkAfterBreak when s_MarkAfterBreak => -- Set out line high -- Done in the mux at the end of file - + -- Preload SOF value, 0 by default r_tx_data <= ir_sof_value; r_data_addr <= (others => '0'); - + -- wait ir_mab_clk clock cycles - if r_Clk_Count < unsigned(ir_mab_clk) - 3 then + if r_Clk_Count < unsigned(ir_mab_clk) - 3 then r_Clk_Count <= r_Clk_Count + 1; r_SM_Main <= s_MarkAfterBreak; else r_Clk_Count <= (others => '0'); r_SM_Main <= s_StartOfFrame; end if; - + -- go to s_StartOfFrame when s_StartOfFrame => -- Send null byte - + -- go to s_WaitStartOfFrame - r_SM_Main <= s_WaitStartOfFrame; - + r_SM_Main <= s_WaitStartOfFrame; + when s_WaitStartOfFrame => if s_uart_done = '1' then r_SM_Main <= s_DataFrame; r_tx_data <= i_data; else - r_SM_Main <= s_WaitStartOfFrame; + r_SM_Main <= s_WaitStartOfFrame; end if; - + when s_DataFrame => r_SM_Main <= s_WaitDataFrame; - r_data_addr <= r_data_addr + 1; - + r_data_addr <= r_data_addr + 1; + when s_WaitDataFrame => if s_uart_done = '1' then if r_data_addr < unsigned(ir_chan_count) then @@ -155,32 +176,32 @@ begin r_SM_Main <= s_Break; end if; else - r_SM_Main <= s_WaitDataFrame; + r_SM_Main <= s_WaitDataFrame; end if; - + when others => - r_SM_Main <= s_Init; - + r_SM_Main <= s_Init; + end case; end if; end if; end process p_DMX512; with r_SM_Main select s_uart_strobe <= '1' when s_StartOfFrame, - '1' when s_DataFrame, - '0' when others; + '1' when s_DataFrame, + '0' when others; o_addr <= std_logic_vector(r_data_addr); - + -- Memory always selected for now, see if FSM needs to control it o_rden <= '1'; - + -- Uart instance - scalp_hl2_uart_i: scalp_hl2_uart + scalp_hl2_uart_i : scalp_hl2_uart generic map( G_PORT_COUNT => G_PORT_COUNT ) - port map ( + port map( i_clk => i_clk, ir_bit_clk => ir_bit_clk, i_data_valid => s_uart_strobe, @@ -204,12 +225,12 @@ begin o_dmx(I) <= ir_idl_value(I); else case r_SM_Main is - when s_Init => o_dmx(I) <= '0'; - when s_Break => o_dmx(I) <= '0'; - when s_MarkAfterBreak => o_dmx(I) <= '1'; - when others => o_dmx(I) <= s_uartdmx(I); + when s_Init => o_dmx(I) <= '0'; + when s_Break => o_dmx(I) <= '0'; + when s_MarkAfterBreak => o_dmx(I) <= '1'; + when others => o_dmx(I) <= s_uartdmx(I); end case; - end if; + end if; end loop; end process; diff --git a/ips/hw/scalp_hl2/src/hdl/scalp_hl2_pkg.vhd b/ips/hw/scalp_hl2/src/hdl/scalp_hl2_pkg.vhd index 6a30bd1..d26c84e 100755 --- a/ips/hw/scalp_hl2/src/hdl/scalp_hl2_pkg.vhd +++ b/ips/hw/scalp_hl2/src/hdl/scalp_hl2_pkg.vhd @@ -1,73 +1,94 @@ +---------------------------------------------------------------------------------- +-- _ _ +-- | |_ ___ _ __(_)__ _ +-- | ' \/ -_) '_ \ / _` | +-- |_||_\___| .__/_\__,_| +-- |_| +-- +---------------------------------------------------------------------------------- +-- +-- Company: hepia +-- Author: Quentin Berthet <quentin.berthet@hesge.ch +-- +-- Module Name: scalp_hl2_pkg +-- Target Device: hepia-cores.ch:scalp_node:part0:0.1 xc7z015clg485-2 +-- Tool version: 2019.2 +-- Description: SCALP - HEPIALight2 configuration package +-- +-- Last update: 2020/12/17 12:09:59 +-- +--------------------------------------------------------------------------------- + library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; +use IEEE.STD_LOGIC_1164.all; +use IEEE.NUMERIC_STD.all; package scalp_hl2_pkg is -- Info register ---------------------------------------------------------- -- PORT_COUNT - constant C_REG_PORT_COUNT_SIZE : integer := 8; - constant C_REG_PORT_COUNT_POS : integer := 8; + constant C_REG_PORT_COUNT_SIZE : integer := 8; + constant C_REG_PORT_COUNT_POS : integer := 8; --constant C_REG_PORT_COUNT_RESET_VAL : integer := 0; GENERIC -- IP_REV_MAJ - constant C_REG_IP_REV_MAJ_SIZE : integer := 4; - constant C_REG_IP_REV_MAJ_POS : integer := 4; - constant C_REG_IP_REV_MAJ_RESET_VAL : integer := 1; + constant C_REG_IP_REV_MAJ_SIZE : integer := 4; + constant C_REG_IP_REV_MAJ_POS : integer := 4; + constant C_REG_IP_REV_MAJ_RESET_VAL : integer := 1; -- IP_REV_MIN - constant C_REG_IP_REV_MIN_SIZE : integer := 4; - constant C_REG_IP_REV_MIN_POS : integer := 0; - constant C_REG_IP_REV_MIN_RESET_VAL : integer := 0; + constant C_REG_IP_REV_MIN_SIZE : integer := 4; + constant C_REG_IP_REV_MIN_POS : integer := 0; + constant C_REG_IP_REV_MIN_RESET_VAL : integer := 0; -- Global clock config register ------------------------------------------- -- BIT_CLK - constant C_REG_BIT_CLK_SIZE : integer := 16; - constant C_REG_BIT_CLK_POS : integer := 0; - constant C_REG_BIT_CLK_RESET_VAL : integer := 200; + constant C_REG_BIT_CLK_SIZE : integer := 16; + constant C_REG_BIT_CLK_POS : integer := 0; + constant C_REG_BIT_CLK_RESET_VAL : integer := 200; -- Global break config register ------------------------------------------- - + -- MAB_CLK - constant C_REG_MAB_CLK_SIZE : integer := 16; - constant C_REG_MAB_CLK_POS : integer := 16; - constant C_REG_MAB_CLK_RESET_VAL : integer := 3*C_REG_BIT_CLK_RESET_VAL; + constant C_REG_MAB_CLK_SIZE : integer := 16; + constant C_REG_MAB_CLK_POS : integer := 16; + constant C_REG_MAB_CLK_RESET_VAL : integer := 3 * C_REG_BIT_CLK_RESET_VAL; -- BREAK_CLK - constant C_REG_BREAK_CLK_SIZE : integer := 16; - constant C_REG_BREAK_CLK_POS : integer := 0; - constant C_REG_BREAK_CLK_RESET_VAL : integer := 23*C_REG_BIT_CLK_RESET_VAL; - + constant C_REG_BREAK_CLK_SIZE : integer := 16; + constant C_REG_BREAK_CLK_POS : integer := 0; + constant C_REG_BREAK_CLK_RESET_VAL : integer := 23 * C_REG_BIT_CLK_RESET_VAL; + -- Global control register ------------------------------------------------ -- CHAN_COUNT - constant C_REG_CHAN_COUNT_SIZE : integer := 12; - constant C_REG_CHAN_COUNT_POS : integer := 16; - constant C_REG_CHAN_COUNT_RESET_VAL : integer := 512; + constant C_REG_CHAN_COUNT_SIZE : integer := 12; + constant C_REG_CHAN_COUNT_POS : integer := 16; + constant C_REG_CHAN_COUNT_RESET_VAL : integer := 512; -- GLOBAL_EN - constant C_REG_GLOBAL_EN_SIZE : integer := 1; - constant C_REG_GLOBAL_EN_POS : integer := 0; - constant C_REG_GLOBAL_EN_RESET_VAL : integer := 1; + constant C_REG_GLOBAL_EN_SIZE : integer := 1; + constant C_REG_GLOBAL_EN_POS : integer := 0; + constant C_REG_GLOBAL_EN_RESET_VAL : integer := 1; -- Port N control register ------------------------------------------------ -- SOF_VALUE - constant C_REG_SOF_VALUE_SIZE : integer := 8; - constant C_REG_SOF_VALUE_POS : integer := 8; - constant C_REG_SOF_VALUE_RESET_VAL : integer := 0; + constant C_REG_SOF_VALUE_SIZE : integer := 8; + constant C_REG_SOF_VALUE_POS : integer := 8; + constant C_REG_SOF_VALUE_RESET_VAL : integer := 0; -- IDL - constant C_REG_IDL_SIZE : integer := 1; - constant C_REG_IDL_POS : integer := 1; - constant C_REG_IDL_RESET_VAL : integer := 0; + constant C_REG_IDL_SIZE : integer := 1; + constant C_REG_IDL_POS : integer := 1; + constant C_REG_IDL_RESET_VAL : integer := 0; -- EN - constant C_REG_EN_SIZE : integer := 1; - constant C_REG_EN_POS : integer := 0; - constant C_REG_EN_RESET_VAL : integer := 1; + constant C_REG_EN_SIZE : integer := 1; + constant C_REG_EN_POS : integer := 0; + constant C_REG_EN_RESET_VAL : integer := 1; end scalp_hl2_pkg; diff --git a/ips/hw/scalp_hl2/src/hdl/scalp_hl2_uart.vhd b/ips/hw/scalp_hl2/src/hdl/scalp_hl2_uart.vhd index d1962a5..83e4daa 100755 --- a/ips/hw/scalp_hl2/src/hdl/scalp_hl2_uart.vhd +++ b/ips/hw/scalp_hl2/src/hdl/scalp_hl2_uart.vhd @@ -1,3 +1,25 @@ +---------------------------------------------------------------------------------- +-- _ _ +-- | |_ ___ _ __(_)__ _ +-- | ' \/ -_) '_ \ / _` | +-- |_||_\___| .__/_\__,_| +-- |_| +-- +---------------------------------------------------------------------------------- +-- +-- Company: hepia +-- Author: Quentin Berthet <quentin.berthet@hesge.ch +-- +-- Module Name: scalp_hl2_uart +-- Target Device: hepia-cores.ch:scalp_node:part0:0.1 xc7z015clg485-2 +-- Tool version: 2019.2 +-- Description: Simple unidirectional UART, with configurable port count. +-- Implemented with DMX-512 in mind.. +-- +-- Last update: 2020/12/17 12:10:06 +-- +--------------------------------------------------------------------------------- + library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; @@ -6,140 +28,130 @@ library xil_defaultlib; use xil_defaultlib.scalp_hl2_pkg.all; entity scalp_hl2_uart is - generic ( - G_PORT_COUNT : integer := 1 + generic ( + G_PORT_COUNT : integer := 1 ); - port ( - i_clk : in std_logic; - ir_bit_clk : in std_logic_vector(C_REG_BIT_CLK_SIZE-1 downto 0); - i_data_valid : in std_logic; - i_data : in std_logic_vector((8*G_PORT_COUNT)-1 downto 0); - o_active : out std_logic; - o_dmx : out std_logic_vector(G_PORT_COUNT-1 downto 0); - o_done : out std_logic + port ( + i_clk : in std_logic; + ir_bit_clk : in std_logic_vector(C_REG_BIT_CLK_SIZE - 1 downto 0); + i_data_valid : in std_logic; + i_data : in std_logic_vector((8 * G_PORT_COUNT) - 1 downto 0); + o_active : out std_logic; + o_dmx : out std_logic_vector(G_PORT_COUNT - 1 downto 0); + o_done : out std_logic ); end scalp_hl2_uart; - - architecture RTL of scalp_hl2_uart is - type t_SM_Main is ( - s_Idle, - s_TX_Start_Bit, - s_TX_Data_Bits, - s_TX_Stop_Bit1, - s_TX_Stop_Bit2, - s_Cleanup - ); + type t_SM_Main is ( + s_Idle, + s_TX_Start_Bit, + s_TX_Data_Bits, + s_TX_Stop_Bit1, + s_TX_Stop_Bit2, + s_Cleanup + ); - signal r_SM_Main : t_SM_Main := s_Idle; + signal r_SM_Main : t_SM_Main := s_Idle; - signal r_clk_counter : unsigned(C_REG_BIT_CLK_SIZE-1 downto 0); - signal r_bit_index : integer range 0 to 7; - signal r_data : std_logic_vector((8*G_PORT_COUNT)-1 downto 0); - signal r_done : std_logic; + signal r_clk_counter : unsigned(C_REG_BIT_CLK_SIZE - 1 downto 0); + signal r_bit_index : integer range 0 to 7; + signal r_data : std_logic_vector((8 * G_PORT_COUNT) - 1 downto 0); + signal r_done : std_logic; begin - p_UART_TX : process (i_clk) - begin - if rising_edge(i_clk) then - - case r_SM_Main is - - when s_Idle => - o_active <= '0'; - o_dmx <= (others => '1'); -- Drive Line High for Idle - r_done <= '0'; - r_clk_counter <= (others => '0'); - r_bit_index <= 0; - - if i_data_valid = '1' then - r_data <= i_data; - r_SM_Main <= s_TX_Start_Bit; - else - r_SM_Main <= s_Idle; - end if; - - -- Send out Start Bit. Start bit = 0 - when s_TX_Start_Bit => - o_active <= '1'; - o_dmx <= (others => '0'); - - -- Wait ir_bit_clk clock cycles for start bit to finish - if r_clk_counter < unsigned(ir_bit_clk) - 1 then - r_clk_counter <= r_clk_counter + 1; - r_SM_Main <= s_TX_Start_Bit; - else - r_clk_counter <= (others => '0'); - r_SM_Main <= s_TX_Data_Bits; - end if; - - - -- Wait ir_bit_clk clock cycles for data bits to finish - when s_TX_Data_Bits => - for I in 0 to G_PORT_COUNT-1 loop - o_dmx(I) <= r_data(r_bit_index+(8*I)); - end loop; - - if r_clk_counter < unsigned(ir_bit_clk) - 1 then - r_clk_counter <= r_clk_counter + 1; - r_SM_Main <= s_TX_Data_Bits; - else - r_clk_counter <= (others => '0'); - - -- Check if we have sent out all bits - if r_bit_index < 7 then - r_bit_index <= r_bit_index + 1; - r_SM_Main <= s_TX_Data_Bits; - else - r_bit_index <= 0; - r_SM_Main <= s_TX_Stop_Bit1; - end if; - end if; - - - -- Send out first stop bit - when s_TX_Stop_Bit1 => - o_dmx <= (others => '1'); - - -- Wait ir_bit_clk clock cycles for Stop bit to finish - if r_clk_counter < unsigned(ir_bit_clk) - 1 then - r_clk_counter <= r_clk_counter + 1; - r_SM_Main <= s_TX_Stop_Bit1; - else - r_clk_counter <= (others => '0'); - r_SM_Main <= s_TX_Stop_Bit2; - end if; - - - -- Send out second stop bit - when s_TX_Stop_Bit2 => - o_dmx <= (others => '1'); - - -- Wait ir_bit_clk clock cycles for Stop bit to finish - if r_clk_counter < unsigned(ir_bit_clk) - 2 then - r_clk_counter <= r_clk_counter + 1; - r_SM_Main <= s_TX_Stop_Bit2; - else - r_clk_counter <= (others => '0'); - r_SM_Main <= s_Cleanup; - end if; - - -- Stay here 1 clock - when s_Cleanup => - o_active <= '0'; - r_done <= '1'; - r_SM_Main <= s_Idle; - - - when others => - r_SM_Main <= s_Idle; - - end case; - end if; - end process p_UART_TX; - - o_done <= r_done; + p_UART_TX : process (i_clk) + begin + if rising_edge(i_clk) then + + case r_SM_Main is + + when s_Idle => + o_active <= '0'; + o_dmx <= (others => '1'); -- Drive Line High for Idle + r_done <= '0'; + r_clk_counter <= (others => '0'); + r_bit_index <= 0; + + if i_data_valid = '1' then + r_data <= i_data; + r_SM_Main <= s_TX_Start_Bit; + else + r_SM_Main <= s_Idle; + end if; + + -- Send out Start Bit. Start bit = 0 + when s_TX_Start_Bit => + o_active <= '1'; + o_dmx <= (others => '0'); + + -- Wait ir_bit_clk clock cycles for start bit to finish + if r_clk_counter < unsigned(ir_bit_clk) - 1 then + r_clk_counter <= r_clk_counter + 1; + r_SM_Main <= s_TX_Start_Bit; + else + r_clk_counter <= (others => '0'); + r_SM_Main <= s_TX_Data_Bits; + end if; + -- Wait ir_bit_clk clock cycles for data bits to finish + when s_TX_Data_Bits => + for I in 0 to G_PORT_COUNT - 1 loop + o_dmx(I) <= r_data(r_bit_index + (8 * I)); + end loop; + + if r_clk_counter < unsigned(ir_bit_clk) - 1 then + r_clk_counter <= r_clk_counter + 1; + r_SM_Main <= s_TX_Data_Bits; + else + r_clk_counter <= (others => '0'); + + -- Check if we have sent out all bits + if r_bit_index < 7 then + r_bit_index <= r_bit_index + 1; + r_SM_Main <= s_TX_Data_Bits; + else + r_bit_index <= 0; + r_SM_Main <= s_TX_Stop_Bit1; + end if; + end if; + -- Send out first stop bit + when s_TX_Stop_Bit1 => + o_dmx <= (others => '1'); + + -- Wait ir_bit_clk clock cycles for Stop bit to finish + if r_clk_counter < unsigned(ir_bit_clk) - 1 then + r_clk_counter <= r_clk_counter + 1; + r_SM_Main <= s_TX_Stop_Bit1; + else + r_clk_counter <= (others => '0'); + r_SM_Main <= s_TX_Stop_Bit2; + end if; + -- Send out second stop bit + when s_TX_Stop_Bit2 => + o_dmx <= (others => '1'); + + -- Wait ir_bit_clk clock cycles for Stop bit to finish + if r_clk_counter < unsigned(ir_bit_clk) - 2 then + r_clk_counter <= r_clk_counter + 1; + r_SM_Main <= s_TX_Stop_Bit2; + else + r_clk_counter <= (others => '0'); + r_SM_Main <= s_Cleanup; + end if; + + -- Stay here 1 clock + when s_Cleanup => + o_active <= '0'; + r_done <= '1'; + r_SM_Main <= s_Idle; + when others => + r_SM_Main <= s_Idle; + + end case; + end if; + end process p_UART_TX; + + o_done <= r_done; end RTL; \ No newline at end of file -- GitLab