URL
https://opencores.org/ocsvn/spi_slave/spi_slave/trunk
Subversion Repositories spi_slave
Compare Revisions
- This comparison shows the changes necessary to convert path
/spi_slave/trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl
- from Rev 33 to Rev 35
- ↔ Reverse comparison
Rev 33 → Rev 35
/crc_core.vhd
0,0 → 1,127
|
library ieee; |
use ieee.std_logic_1164.all; |
|
entity crc_core is |
|
generic ( |
C_SR_WIDTH : integer := 32); |
port ( |
rst : in std_logic; |
opb_clk : in std_logic; |
crc_en : in std_logic; |
crc_clr : in std_logic; |
opb_m_last_block : in std_logic; |
-- RX |
fifo_rx_en : in std_logic; |
fifo_rx_data : in std_logic_vector(C_SR_WIDTH-1 downto 0); |
opb_rx_crc_value : out std_logic_vector(C_SR_WIDTH-1 downto 0); |
-- TX |
fifo_tx_en : in std_logic; |
fifo_tx_data : in std_logic_vector(C_SR_WIDTH-1 downto 0); |
tx_crc_insert : out std_logic; |
opb_tx_crc_value : out std_logic_vector(C_SR_WIDTH-1 downto 0)); |
end crc_core; |
|
|
architecture behavior of crc_core is |
component crc_gen |
generic ( |
C_SR_WIDTH : integer; |
crc_start_value : std_logic_vector(31 downto 0)); |
port ( |
clk : in std_logic; |
crc_clear : in std_logic; |
crc_en : in std_logic; |
crc_data_in : in std_logic_vector(C_SR_WIDTH-1 downto 0); |
crc_data_out : out std_logic_vector(C_SR_WIDTH-1 downto 0)); |
end component; |
|
signal rx_crc_en : std_logic; |
signal tx_crc_en : std_logic; |
|
|
type state_define is (idle, |
tx_insert_crc, |
wait_done); |
signal state : state_define; |
|
begin -- behavior |
|
--* RX CRC_GEN |
crc_gen_rx : crc_gen |
generic map ( |
C_SR_WIDTH => C_SR_WIDTH, |
crc_start_value => (others => '1')) |
port map ( |
clk => OPB_Clk, |
crc_clear => crc_clr, |
crc_en => rx_crc_en, |
crc_data_in => fifo_rx_data, |
crc_data_out => opb_rx_crc_value); |
|
-- disable crc_generation for last data block |
rx_crc_en <= '1' when (crc_en = '1' and fifo_rx_en = '1' and opb_m_last_block = '0') else |
'0'; |
|
----------------------------------------------------------------------------- |
--* TX CRC_GEN |
crc_gen_tx : crc_gen |
generic map ( |
C_SR_WIDTH => C_SR_WIDTH, |
crc_start_value => (others => '1')) |
port map ( |
clk => OPB_Clk, |
crc_clear => crc_clr, |
crc_en => tx_crc_en, |
crc_data_in => fifo_tx_data, |
crc_data_out => opb_tx_crc_value); |
|
-- disable crc_generation for last data block |
tx_crc_en <= '1' when (crc_en = '1' and fifo_tx_en = '1' and opb_m_last_block = '0') else |
'0'; |
|
process(rst, OPB_Clk) |
begin |
if (rst = '1') then |
tx_crc_insert <= '0'; |
state <= idle; |
elsif rising_edge(OPB_Clk) then |
case state is |
when idle => |
if (opb_m_last_block = '1') then |
tx_crc_insert <= '1'; |
state <= tx_insert_crc; |
else |
tx_crc_insert <= '0'; |
state <= idle; |
end if; |
|
when tx_insert_crc => |
if (opb_m_last_block = '0') then |
-- abort |
tx_crc_insert <= '0'; |
state <= idle; |
elsif (fifo_tx_en = '1') then |
tx_crc_insert <= '0'; |
state <= wait_done; |
else |
state <= tx_insert_crc; |
end if; |
|
when wait_done => |
if (opb_m_last_block = '0') then |
tx_crc_insert <= '0'; |
state <= idle; |
|
else |
state <= wait_done; |
end if; |
|
when others => |
state <= idle; |
end case; |
|
end if; |
end process; |
end behavior; |
/opb_spi_slave.vhd
0,0 → 1,640
------------------------------------------------------------------------------- |
------------------------------------------------------- |
--! @file |
--! @brief 2:1 Mux using with-select |
------------------------------------------------------- |
|
--* |
--* @short Top entity of the project opi_spi_slave |
--* |
--* @generic C_FAMILY virtex-4 and generic supported |
|
--* @version: 1.1 |
--* @date: 2007-11-19 |
--/ |
-- Version 1.1 |
-- Bugfix |
-- IRQ-Flag RX_Overflow shows prog_empty insteed rx_overflow |
-- opb_irq_flg(5) <= opb_fifo_flg(9); to opb_irq_flg(5) <= opb_fifo_flg(8); |
|
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use IEEE.STD_LOGIC_UNSIGNED.all; |
|
|
library UNISIM; |
use UNISIM.vcomponents.all; |
|
library work; |
use work.opb_spi_slave_pack.all; |
|
|
entity opb_spi_slave is |
|
generic ( |
C_BASEADDR : std_logic_vector(0 to 31) := X"00000000"; |
C_HIGHADDR : std_logic_vector(0 to 31) := X"FFFFFFFF"; |
C_USER_ID_CODE : integer := 0; |
C_OPB_AWIDTH : integer := 32; |
C_OPB_DWIDTH : integer := 32; |
|
C_FAMILY : string := "virtex4"; |
-- user ports |
C_SR_WIDTH : integer := 8; |
C_MSB_FIRST : boolean := true; |
C_CPOL : integer range 0 to 1 := 0; |
C_PHA : integer range 0 to 1 := 0; |
C_FIFO_SIZE_WIDTH : integer range 4 to 7 := 5; -- depth 32 |
C_DMA_EN : boolean := false; |
C_CRC_EN : boolean := false); |
|
port ( |
-- OPB signals (Slave Side) |
OPB_ABus : in std_logic_vector(0 to C_OPB_AWIDTH-1); |
OPB_BE : in std_logic_vector(0 to C_OPB_DWIDTH/8-1); |
OPB_Clk : in std_logic; |
OPB_DBus : in std_logic_vector(0 to C_OPB_DWIDTH-1); |
OPB_RNW : in std_logic; |
OPB_Rst : in std_logic; |
OPB_select : in std_logic; |
OPB_seqAddr : in std_logic; |
Sln_DBus : out std_logic_vector(0 to C_OPB_DWIDTH-1); |
Sln_errAck : out std_logic; |
Sln_retry : out std_logic; |
Sln_toutSup : out std_logic; |
Sln_xferAck : out std_logic; |
|
-- OPB signals (Master Side) |
-- Arbitration |
M_request : out std_logic; |
MOPB_MGrant : in std_logic; |
M_busLock : out std_logic; |
-- |
M_ABus : out std_logic_vector(0 to C_OPB_AWIDTH-1); |
M_BE : out std_logic_vector(0 to C_OPB_DWIDTH/8-1); |
M_DBus : out std_logic_vector(0 to C_OPB_DWIDTH-1); |
M_RNW : out std_logic; |
M_select : out std_logic; |
M_seqAddr : out std_logic; |
MOPB_errAck : in std_logic; |
MOPB_retry : in std_logic; |
MOPB_timeout : in std_logic; |
MOPB_xferAck : in std_logic; |
-- spi ports |
sclk : in std_logic; |
ss_n : in std_logic; |
mosi : in std_logic; |
miso_o : out std_logic; |
miso_i : in std_logic; |
miso_t : out std_logic; |
-- irq output |
opb_irq : out std_logic); |
|
end opb_spi_slave; |
|
architecture behavior of opb_spi_slave is |
|
component opb_if |
generic ( |
C_BASEADDR : std_logic_vector(0 to 31); |
C_HIGHADDR : std_logic_vector(0 to 31); |
C_USER_ID_CODE : integer; |
C_OPB_AWIDTH : integer; |
C_OPB_DWIDTH : integer; |
C_FAMILY : string; |
C_SR_WIDTH : integer; |
C_FIFO_SIZE_WIDTH : integer; |
C_DMA_EN : boolean; |
C_CRC_EN : boolean); |
port ( |
OPB_ABus : in std_logic_vector(0 to C_OPB_AWIDTH-1); |
OPB_BE : in std_logic_vector(0 to C_OPB_DWIDTH/8-1); |
OPB_Clk : in std_logic; |
OPB_DBus : in std_logic_vector(0 to C_OPB_DWIDTH-1); |
OPB_RNW : in std_logic; |
OPB_Rst : in std_logic; |
OPB_select : in std_logic; |
OPB_seqAddr : in std_logic; |
Sln_DBus : out std_logic_vector(0 to C_OPB_DWIDTH-1); |
Sln_errAck : out std_logic; |
Sln_retry : out std_logic; |
Sln_toutSup : out std_logic; |
Sln_xferAck : out std_logic; |
opb_s_tx_en : out std_logic; |
opb_s_tx_data : out std_logic_vector(C_SR_WIDTH-1 downto 0); |
opb_s_rx_en : out std_logic; |
opb_s_rx_data : in std_logic_vector(C_SR_WIDTH-1 downto 0); |
opb_ctl_reg : out std_logic_vector(C_OPB_CTL_REG_WIDTH-1 downto 0); |
tx_thresh : out std_logic_vector((2*C_FIFO_SIZE_WIDTH)-1 downto 0); |
rx_thresh : out std_logic_vector((2*C_FIFO_SIZE_WIDTH)-1 downto 0); |
opb_fifo_flg : in std_logic_vector(C_NUM_FLG-1 downto 0); |
opb_dgie : out std_logic; |
opb_ier : out std_logic_vector(C_NUM_INT-1 downto 0); |
opb_isr : in std_logic_vector(C_NUM_INT-1 downto 0); |
opb_isr_clr : out std_logic_vector(C_NUM_INT-1 downto 0); |
opb_tx_dma_addr : out std_logic_vector(C_OPB_DWIDTH-1 downto 0); |
opb_tx_dma_ctl : out std_logic_vector(0 downto 0); |
opb_tx_dma_num : out std_logic_vector(C_WIDTH_DMA_NUM-1 downto 0); |
opb_rx_dma_addr : out std_logic_vector(C_OPB_DWIDTH-1 downto 0); |
opb_rx_dma_ctl : out std_logic_vector(0 downto 0); |
opb_rx_dma_num : out std_logic_vector(C_WIDTH_DMA_NUM-1 downto 0); |
opb_rx_crc_value : in std_logic_vector(C_SR_WIDTH-1 downto 0); |
opb_tx_crc_value : in std_logic_vector(C_SR_WIDTH-1 downto 0)); |
|
end component; |
|
|
component opb_m_if |
generic ( |
C_BASEADDR : std_logic_vector(0 to 31); |
C_HIGHADDR : std_logic_vector(0 to 31); |
C_USER_ID_CODE : integer; |
C_OPB_AWIDTH : integer; |
C_OPB_DWIDTH : integer; |
C_FAMILY : string; |
C_SR_WIDTH : integer; |
C_MSB_FIRST : boolean; |
C_CPOL : integer range 0 to 1; |
C_PHA : integer range 0 to 1; |
C_FIFO_SIZE_WIDTH : integer range 4 to 7); |
port ( |
OPB_Clk : in std_logic; |
OPB_Rst : in std_logic; |
OPB_DBus : in std_logic_vector(0 to C_OPB_DWIDTH-1); |
M_request : out std_logic; |
MOPB_MGrant : in std_logic; |
M_busLock : out std_logic; |
M_ABus : out std_logic_vector(0 to C_OPB_AWIDTH-1); |
M_BE : out std_logic_vector(0 to C_OPB_DWIDTH/8-1); |
M_DBus : out std_logic_vector(0 to C_OPB_DWIDTH-1); |
M_RNW : out std_logic; |
M_select : out std_logic; |
M_seqAddr : out std_logic; |
MOPB_errAck : in std_logic; |
MOPB_retry : in std_logic; |
MOPB_timeout : in std_logic; |
MOPB_xferAck : in std_logic; |
opb_m_tx_req : in std_logic; |
opb_m_tx_en : out std_logic; |
opb_m_tx_data : out std_logic_vector(C_SR_WIDTH-1 downto 0); |
opb_tx_dma_ctl : in std_logic_vector(0 downto 0); |
opb_tx_dma_addr : in std_logic_vector(C_OPB_DWIDTH-1 downto 0); |
opb_tx_dma_num : in std_logic_vector(C_WIDTH_DMA_NUM-1 downto 0); |
opb_tx_dma_done : out std_logic; |
opb_m_rx_req : in std_logic; |
opb_m_rx_en : out std_logic; |
opb_m_rx_data : in std_logic_vector(C_SR_WIDTH-1 downto 0); |
opb_rx_dma_ctl : in std_logic_vector(0 downto 0); |
opb_rx_dma_addr : in std_logic_vector(C_OPB_DWIDTH-1 downto 0); |
opb_rx_dma_num : in std_logic_vector(C_WIDTH_DMA_NUM-1 downto 0); |
opb_rx_dma_done : out std_logic; |
opb_abort_flg : out std_logic; |
opb_m_last_block : out std_logic); |
end component; |
|
component shift_register |
generic ( |
C_SR_WIDTH : integer; |
C_MSB_FIRST : boolean; |
C_CPOL : integer range 0 to 1; |
C_PHA : integer range 0 to 1); |
port ( |
rst : in std_logic; |
opb_ctl_reg : in std_logic_vector(C_OPB_CTL_REG_WIDTH-1 downto 0); |
sclk : in std_logic; |
ss_n : in std_logic; |
mosi : in std_logic; |
miso_o : out std_logic; |
miso_i : in std_logic; |
miso_t : out std_logic; |
sr_tx_clk : out std_logic; |
sr_tx_en : out std_logic; |
sr_tx_data : in std_logic_vector(C_SR_WIDTH-1 downto 0); |
sr_rx_clk : out std_logic; |
sr_rx_en : out std_logic; |
sr_rx_data : out std_logic_vector(C_SR_WIDTH-1 downto 0)); |
end component; |
|
component fifo |
generic ( |
C_FIFO_WIDTH : integer; |
C_FIFO_SIZE_WIDTH : integer; |
C_SYNC_TO : string); |
port ( |
rst : in std_logic; |
wr_clk : in std_logic; |
wr_en : in std_logic; |
din : in std_logic_vector(C_SR_WIDTH-1 downto 0); |
rd_clk : in std_logic; |
rd_en : in std_logic; |
dout : out std_logic_vector(C_SR_WIDTH-1 downto 0); |
empty : out std_logic; |
full : out std_logic; |
overflow : out std_logic; |
underflow : out std_logic; |
prog_empty_thresh : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); |
prog_full_thresh : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); |
prog_empty : out std_logic; |
prog_full : out std_logic); |
end component; |
|
component irq_ctl |
generic ( |
C_ACTIVE_EDGE : std_logic); |
port ( |
rst : in std_logic; |
clk : in std_logic; |
opb_fifo_flg : in std_logic; |
opb_ier : in std_logic; |
opb_isr : out std_logic; |
opb_isr_clr : in std_logic); |
end component; |
|
component crc_core |
generic ( |
C_SR_WIDTH : integer); |
port ( |
rst : in std_logic; |
opb_clk : in std_logic; |
crc_en : in std_logic; |
crc_clr : in std_logic; |
opb_m_last_block : in std_logic; |
fifo_rx_en : in std_logic; |
fifo_rx_data : in std_logic_vector(C_SR_WIDTH-1 downto 0); |
opb_rx_crc_value : out std_logic_vector(C_SR_WIDTH-1 downto 0); |
fifo_tx_en : in std_logic; |
fifo_tx_data : in std_logic_vector(C_SR_WIDTH-1 downto 0); |
tx_crc_insert : out std_logic; |
opb_tx_crc_value : out std_logic_vector(C_SR_WIDTH-1 downto 0)); |
end component; |
|
-- opb_if |
signal opb_ctl_reg : std_logic_vector(C_OPB_CTL_REG_WIDTH-1 downto 0); |
|
signal opb_s_tx_en : std_logic; |
signal opb_s_tx_data : std_logic_vector(C_SR_WIDTH-1 downto 0); |
signal opb_s_rx_en : std_logic; |
signal opb_s_rx_data : std_logic_vector(C_SR_WIDTH-1 downto 0); |
|
signal tx_thresh : std_logic_vector((2*C_FIFO_SIZE_WIDTH)-1 downto 0); |
signal rx_thresh : std_logic_vector((2*C_FIFO_SIZE_WIDTH)-1 downto 0); |
|
signal opb_tx_dma_addr : std_logic_vector(C_OPB_DWIDTH-1 downto 0); |
signal opb_tx_dma_ctl : std_logic_vector(0 downto 0); |
signal opb_tx_dma_num : std_logic_vector(C_WIDTH_DMA_NUM-1 downto 0); |
signal opb_rx_dma_addr : std_logic_vector(C_OPB_DWIDTH-1 downto 0); |
signal opb_rx_dma_ctl : std_logic_vector(0 downto 0); |
signal opb_rx_dma_num : std_logic_vector(C_WIDTH_DMA_NUM-1 downto 0); |
|
signal opb_rx_crc_value : std_logic_vector(C_SR_WIDTH-1 downto 0); |
signal opb_tx_crc_value : std_logic_vector(C_SR_WIDTH-1 downto 0); |
|
-- opb_m_if |
signal opb_m_tx_en : std_logic; |
signal opb_m_tx_data : std_logic_vector(C_SR_WIDTH-1 downto 0); |
signal opb_m_rx_en : std_logic; |
signal opb_m_rx_data : std_logic_vector(C_SR_WIDTH-1 downto 0); |
signal opb_abort_flg : std_logic; |
signal opb_m_last_block : std_logic; |
|
-- shift_register |
signal sr_tx_clk : std_logic; |
signal sr_tx_en : std_logic; |
signal sr_tx_data : std_logic_vector(C_SR_WIDTH-1 downto 0); |
signal sr_rx_clk : std_logic; |
signal sr_rx_en : std_logic; |
signal sr_rx_data : std_logic_vector(C_SR_WIDTH-1 downto 0); |
|
signal sclk_ibuf : std_logic; |
signal sclk_bufr : std_logic; |
|
signal opb_fifo_flg : std_logic_vector(C_NUM_FLG-1 downto 0); |
signal opb_irq_flg : std_logic_vector(C_NUM_INT-1 downto 0) := (others => '0'); |
signal rst : std_logic; |
|
|
signal opb_dgie : std_logic; |
signal opb_ier : std_logic_vector(C_NUM_INT-1 downto 0); |
signal opb_isr : std_logic_vector(C_NUM_INT-1 downto 0); |
signal opb_isr_clr : std_logic_vector(C_NUM_INT-1 downto 0); |
|
-- opb_spi_slave |
signal fifo_tx_en : std_logic; |
signal fifo_tx_data : std_logic_vector(C_SR_WIDTH-1 downto 0); |
signal fifo_rx_en : std_logic; |
signal fifo_rx_data : std_logic_vector(C_SR_WIDTH-1 downto 0); |
|
-- rx crc_core |
signal crc_clr : std_logic; |
signal crc_en : std_logic; |
signal tx_crc_insert : std_logic; |
|
begin -- behavior |
|
--* |
virtex4_slk_buf : if C_FAMILY = "virtex4" generate |
--* If C_FAMILY=Virtex-4 use "IBUF" |
IBUF_1 : IBUF |
port map ( |
I => sclk, |
O => sclk_ibuf); |
|
--* If C_FAMILY=Virtex-4 use "BUFR" |
BUFR_1 : BUFR |
generic map ( |
BUFR_DIVIDE => "BYPASS", |
SIM_DEVICE => "VIRTEX4") |
port map ( |
O => sclk_bufr, |
CE => '0', |
CLR => '0', |
I => sclk_ibuf); |
end generate virtex4_slk_buf; |
|
generic_sclk_buf : if C_FAMILY /= "virtex4" generate |
sclk_bufr <= sclk; |
end generate generic_sclk_buf; |
|
--* OPB-Slave Interface(Register-Interface) |
opb_if_2 : opb_if |
generic map ( |
C_BASEADDR => C_BASEADDR, |
C_HIGHADDR => C_HIGHADDR, |
C_USER_ID_CODE => C_USER_ID_CODE, |
C_OPB_AWIDTH => C_OPB_AWIDTH, |
C_OPB_DWIDTH => C_OPB_DWIDTH, |
C_FAMILY => C_FAMILY, |
C_SR_WIDTH => C_SR_WIDTH, |
C_FIFO_SIZE_WIDTH => C_FIFO_SIZE_WIDTH, |
C_DMA_EN => C_DMA_EN, |
C_CRC_EN => C_CRC_EN) |
port map ( |
OPB_ABus => OPB_ABus, |
OPB_BE => OPB_BE, |
OPB_Clk => OPB_Clk, |
OPB_DBus => OPB_DBus, |
OPB_RNW => OPB_RNW, |
OPB_Rst => OPB_Rst, |
OPB_select => OPB_select, |
OPB_seqAddr => OPB_seqAddr, |
Sln_DBus => Sln_DBus, |
Sln_errAck => Sln_errAck, |
Sln_retry => Sln_retry, |
Sln_toutSup => Sln_toutSup, |
Sln_xferAck => Sln_xferAck, |
opb_s_tx_en => opb_s_tx_en, |
opb_s_tx_data => opb_s_tx_data, |
opb_s_rx_en => opb_s_rx_en, |
opb_s_rx_data => opb_s_rx_data, |
opb_ctl_reg => opb_ctl_reg, |
tx_thresh => tx_thresh, |
rx_thresh => rx_thresh, |
opb_fifo_flg => opb_fifo_flg, |
opb_dgie => opb_dgie, |
opb_ier => opb_ier, |
opb_isr => opb_isr, |
opb_isr_clr => opb_isr_clr, |
opb_tx_dma_addr => opb_tx_dma_addr, |
opb_tx_dma_ctl => opb_tx_dma_ctl, |
opb_tx_dma_num => opb_tx_dma_num, |
opb_rx_dma_addr => opb_rx_dma_addr, |
opb_rx_dma_ctl => opb_rx_dma_ctl, |
opb_rx_dma_num => opb_rx_dma_num, |
opb_rx_crc_value => opb_rx_crc_value, |
opb_tx_crc_value => opb_tx_crc_value); |
|
--* OPB-Master-Interface |
--* |
--* (DMA Read/Write Transfers to TX/RX-FIFO) |
|
dma_enable : if (C_DMA_EN = true) generate |
opb_m_if_1 : opb_m_if |
generic map ( |
C_BASEADDR => C_BASEADDR, |
C_HIGHADDR => C_HIGHADDR, |
C_USER_ID_CODE => C_USER_ID_CODE, |
C_OPB_AWIDTH => C_OPB_AWIDTH, |
C_OPB_DWIDTH => C_OPB_DWIDTH, |
C_FAMILY => C_FAMILY, |
C_SR_WIDTH => C_SR_WIDTH, |
C_MSB_FIRST => C_MSB_FIRST, |
C_CPOL => C_CPOL, |
C_PHA => C_PHA, |
C_FIFO_SIZE_WIDTH => C_FIFO_SIZE_WIDTH) |
port map ( |
OPB_Clk => OPB_Clk, |
OPB_Rst => OPB_Rst, |
OPB_DBus => OPB_DBus, |
M_request => M_request, |
MOPB_MGrant => MOPB_MGrant, |
M_busLock => M_busLock, |
M_ABus => M_ABus, |
M_BE => M_BE, |
M_DBus => M_DBus, |
M_RNW => M_RNW, |
M_select => M_select, |
M_seqAddr => M_seqAddr, |
MOPB_errAck => MOPB_errAck, |
MOPB_retry => MOPB_retry, |
MOPB_timeout => MOPB_timeout, |
MOPB_xferAck => MOPB_xferAck, |
opb_m_tx_req => opb_fifo_flg(3), |
opb_m_tx_en => opb_m_tx_en, |
opb_m_tx_data => opb_m_tx_data, |
opb_tx_dma_ctl => opb_tx_dma_ctl, |
opb_tx_dma_addr => opb_tx_dma_addr, |
opb_tx_dma_num => opb_tx_dma_num, |
opb_tx_dma_done => opb_fifo_flg(13), |
opb_m_rx_req => opb_fifo_flg(6), |
opb_m_rx_en => opb_m_rx_en, |
opb_m_rx_data => opb_m_rx_data, |
opb_rx_dma_ctl => opb_rx_dma_ctl, |
opb_rx_dma_addr => opb_rx_dma_addr, |
opb_rx_dma_num => opb_rx_dma_num, |
opb_rx_dma_done => opb_fifo_flg(14), |
opb_abort_flg => opb_abort_flg, |
opb_m_last_block => opb_m_last_block); |
end generate dma_enable; |
|
dma_disable : if (C_DMA_EN = false) generate |
M_request <= '0'; |
M_busLock <= '0'; |
M_ABus <= (others => '0'); |
M_BE <= (others => '0'); |
M_DBus <= (others => '0'); |
M_RNW <= '0'; |
M_select <= '0'; |
M_seqAddr <= '0'; |
opb_m_tx_en <= '0'; |
opb_m_tx_data <= (others => '0'); |
opb_fifo_flg(13) <= '0'; |
opb_m_rx_en <= '0'; |
opb_fifo_flg(14) <= '0'; |
end generate dma_disable; |
|
--* Shift-Register |
shift_register_1 : shift_register |
generic map ( |
C_SR_WIDTH => C_SR_WIDTH, |
C_MSB_FIRST => C_MSB_FIRST, |
C_CPOL => C_CPOL, |
C_PHA => C_PHA) |
port map ( |
rst => rst, |
opb_ctl_reg => opb_ctl_reg, |
sclk => sclk_bufr, |
ss_n => ss_n, |
mosi => mosi, |
miso_o => miso_o, |
miso_i => miso_i, |
miso_t => miso_t, |
sr_tx_clk => sr_tx_clk, |
sr_tx_en => sr_tx_en, |
sr_tx_data => sr_tx_data, |
sr_rx_clk => sr_rx_clk, |
sr_rx_en => sr_rx_en, |
sr_rx_data => sr_rx_data); |
|
--* Transmit FIFO |
tx_fifo_1 : fifo |
generic map ( |
C_FIFO_WIDTH => C_SR_WIDTH, |
C_FIFO_SIZE_WIDTH => C_FIFO_SIZE_WIDTH, |
C_SYNC_TO => "WR") |
port map ( |
-- global |
rst => rst, |
prog_full_thresh => tx_thresh(C_FIFO_SIZE_WIDTH-1 downto 0), |
prog_empty_thresh => tx_thresh((2*C_FIFO_SIZE_WIDTH)-1 downto C_FIFO_SIZE_WIDTH), |
-- write port |
wr_clk => OPB_Clk, |
wr_en => fifo_tx_en, |
din => fifo_tx_data, |
-- flags |
prog_full => opb_fifo_flg(0), |
full => opb_fifo_flg(1), |
overflow => opb_fifo_flg(2), |
-- read port |
rd_clk => sr_tx_clk, |
rd_en => sr_tx_en, |
dout => sr_tx_data, |
-- flags |
prog_empty => opb_fifo_flg(3), |
empty => opb_fifo_flg(4), |
underflow => opb_fifo_flg(5)); |
|
fifo_tx_en <= opb_s_tx_en or opb_m_tx_en; |
fifo_tx_data <= opb_tx_crc_value when (C_CRC_EN and tx_crc_insert = '1') else |
opb_m_tx_data when (opb_tx_dma_ctl(0) = '1') else |
opb_s_tx_data; |
|
--* Receive FIFO |
rx_fifo_1 : fifo |
generic map ( |
C_FIFO_WIDTH => C_SR_WIDTH, |
C_FIFO_SIZE_WIDTH => C_FIFO_SIZE_WIDTH, |
C_SYNC_TO => "RD") |
port map ( |
-- global |
rst => rst, |
prog_full_thresh => rx_thresh(C_FIFO_SIZE_WIDTH-1 downto 0), |
prog_empty_thresh => rx_thresh((2*C_FIFO_SIZE_WIDTH)-1 downto C_FIFO_SIZE_WIDTH), |
-- write port |
wr_clk => sr_rx_clk, |
wr_en => sr_rx_en, |
din => sr_rx_data, |
-- flags |
prog_full => opb_fifo_flg(6), |
full => opb_fifo_flg(7), |
overflow => opb_fifo_flg(8), |
-- read port |
rd_clk => opb_clk, |
rd_en => fifo_rx_en, |
dout => fifo_rx_data, |
-- flags |
prog_empty => opb_fifo_flg(9), |
empty => opb_fifo_flg(10), |
underflow => opb_fifo_flg(11)); |
|
fifo_rx_en <= opb_s_rx_en or opb_m_rx_en; |
opb_s_rx_data <= fifo_rx_data; |
opb_m_rx_data <= fifo_rx_data; |
|
rst <= OPB_Rst or opb_ctl_reg(C_OPB_CTL_REG_RST); |
|
opb_fifo_flg(12) <= ss_n; |
opb_fifo_flg(15) <= opb_abort_flg; |
|
|
|
-- Bit 0 : TX_PROG_EMPTY |
opb_irq_flg(0) <= opb_fifo_flg(3); |
-- Bit 1 : TX_EMPTY |
opb_irq_flg(1) <= opb_fifo_flg(4); |
-- Bit 2 : TX_Underflow |
opb_irq_flg(2) <= opb_fifo_flg(5); |
-- Bit 3 : RX_PROG_FULL |
opb_irq_flg(3) <= opb_fifo_flg(6); |
-- Bit 4 : RX_FULL |
opb_irq_flg(4) <= opb_fifo_flg(7); |
-- Bit 5 : RX_Overflow |
opb_irq_flg(5) <= opb_fifo_flg(8); |
-- Bit 6: CS_H_TO_L |
opb_irq_flg(6) <= not opb_fifo_flg(12); |
-- Bit 7: CS_L_TO_H |
opb_irq_flg(7) <= opb_fifo_flg(12); |
-- Bit 8: TX DMA Done |
opb_irq_flg(8) <= opb_fifo_flg(13); |
-- Bit 9: RX DMA Done |
opb_irq_flg(9) <= opb_fifo_flg(14); |
-- Bit 10: DMA Transfer Abort |
opb_irq_flg(10) <= opb_abort_flg; |
|
--* IRQ Enable, Detection and Flags Control |
irq_gen : for i in 0 to C_NUM_INT-1 generate |
irq_ctl_1 : irq_ctl |
generic map ( |
C_ACTIVE_EDGE => '1') |
port map ( |
rst => rst, |
clk => OPB_Clk, |
opb_fifo_flg => opb_irq_flg(i), |
opb_ier => opb_ier(i), |
opb_isr => opb_isr(i), |
opb_isr_clr => opb_isr_clr(i)); |
end generate irq_gen; |
|
-- assert irq if one Interupt Status bit set |
opb_irq <= '1' when (conv_integer(opb_isr) /= 0 and opb_dgie = '1') else |
'0'; |
|
|
----------------------------------------------------------------------------- |
|
-- clear start_value at power up and soft_reset |
crc_en <= opb_ctl_reg(C_OPB_CTL_REG_CRC_EN); |
crc_clr <= opb_ctl_reg(C_OPB_CTL_REG_CRC_CLR) or rst; |
|
crc_gen : if (C_CRC_EN) generate |
crc_core_1 : crc_core |
generic map ( |
C_SR_WIDTH => C_SR_WIDTH) |
port map ( |
rst => rst, |
opb_clk => opb_clk, |
crc_en => crc_en, |
crc_clr => crc_clr, |
opb_m_last_block => opb_m_last_block, |
fifo_rx_en => fifo_rx_en, |
fifo_rx_data => fifo_rx_data, |
opb_rx_crc_value => opb_rx_crc_value, |
fifo_tx_en => fifo_tx_en, |
fifo_tx_data => fifo_tx_data, |
tx_crc_insert => tx_crc_insert, |
opb_tx_crc_value => opb_tx_crc_value); |
end generate crc_gen; |
|
|
end behavior; |
/crc_gen.vhd
0,0 → 1,76
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
use ieee.std_logic_arith.all; |
|
library work; |
use work.PCK_CRC32_D32.all; |
-- java -jar jacksum.jar -a crc:32,04C11DB7,FFFFFFFF,false,false,00000000 |
-- -q 000000000000000100000002000000030000000400000005000000060000000700000008000000090000000A0000000B0000000C0000000D0000000E0000000F |
-- -x |
-- Result: eb99fa90 64 |
|
use work.PCK_CRC8_D8.all; |
-- java -jar jacksum.jar -a crc:8,07,FF,false,false,00 |
-- -q 000102030405060708090A0B0C0D0E0F |
-- -x |
-- Result: B8 16 |
|
entity crc_gen is |
generic ( |
C_SR_WIDTH : integer := 32; |
crc_start_value : std_logic_vector(31 downto 0) := (others => '1')); |
port ( |
clk : in std_logic; |
crc_clear : in std_logic; |
crc_en : in std_logic; |
crc_data_in : in std_logic_vector(C_SR_WIDTH-1 downto 0); |
crc_data_out : out std_logic_vector(C_SR_WIDTH-1 downto 0)); |
end crc_gen; |
|
architecture rtl of crc_gen is |
signal crc_data_int : std_logic_vector(C_SR_WIDTH-1 downto 0); |
signal crc_data_in_int : std_logic_vector(C_SR_WIDTH-1 downto 0); |
|
begin -- crc_gen |
process(clk) |
begin |
if rising_edge(clk) then |
if (crc_clear = '1') then |
crc_data_int <= crc_start_value(C_SR_WIDTH-1 downto 0); |
elsif (crc_en = '1') then |
case C_SR_WIDTH is |
when 32 => |
crc_data_int <= nextCRC32_D32(crc_data_in_int, crc_data_int); |
when 8 => |
crc_data_int <= nextCRC8_D8(crc_data_in_int, crc_data_int); |
when others => |
-- no crc calculation |
crc_data_int <= (others => '0'); |
end case; |
end if; |
end if; |
end process; |
|
process(crc_data_int) |
begin |
for i in 0 to 7 loop |
crc_data_out(24+7-i) <= not crc_data_int(i); |
crc_data_out(16+7-i) <= not crc_data_int(8+i); |
crc_data_out(8+7-i) <= not crc_data_int(16+i); |
crc_data_out(7-i) <= not crc_data_int(24+i); |
end loop; -- i |
end process; |
|
process(crc_data_in) |
begin |
for i in 0 to 7 loop |
crc_data_in_int(7-i) <= crc_data_in(i); |
crc_data_in_int(8+7-i) <= crc_data_in(8+i); |
crc_data_in_int(16+7-i) <= crc_data_in(16+i); |
crc_data_in_int(24+7-i) <= crc_data_in(24+i); |
end loop; -- i |
end process; |
|
|
end rtl; |
/opb_if.vhd
0,0 → 1,349
------------------------------------------------------------------------------- |
--* |
--* @short OPB-Slave Interface |
--* |
--* Generics described in top entity. |
--* |
--* @see opb_spi_slave |
|
--* @version: 1.0 |
--* @date: 2007-11-11 |
--/ |
------------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
use IEEE.STD_LOGIC_ARITH.all; |
use IEEE.STD_LOGIC_UNSIGNED.all; |
use IEEE.numeric_std.all; -- conv_integer() |
|
library work; |
use work.opb_spi_slave_pack.all; |
|
entity opb_if is |
|
generic ( |
C_BASEADDR : std_logic_vector(0 to 31) := X"00000000"; |
C_HIGHADDR : std_logic_vector(0 to 31) := X"FFFFFFFF"; |
C_USER_ID_CODE : integer := 3; |
C_OPB_AWIDTH : integer := 32; |
C_OPB_DWIDTH : integer := 32; |
C_FAMILY : string := "virtex-4"; |
C_SR_WIDTH : integer := 8; |
C_FIFO_SIZE_WIDTH : integer := 4; |
C_DMA_EN : boolean := false; |
C_CRC_EN : boolean := false); |
port ( |
-- OPB-Bus Signals |
OPB_ABus : in std_logic_vector(0 to C_OPB_AWIDTH-1); |
OPB_BE : in std_logic_vector(0 to C_OPB_DWIDTH/8-1); |
OPB_Clk : in std_logic; |
OPB_DBus : in std_logic_vector(0 to C_OPB_DWIDTH-1); |
OPB_RNW : in std_logic; |
OPB_Rst : in std_logic; |
OPB_select : in std_logic; |
OPB_seqAddr : in std_logic; |
Sln_DBus : out std_logic_vector(0 to C_OPB_DWIDTH-1); |
Sln_errAck : out std_logic; |
Sln_retry : out std_logic; |
Sln_toutSup : out std_logic; |
Sln_xferAck : out std_logic; |
-- fifo ports |
opb_s_tx_en : out std_logic; |
opb_s_tx_data : out std_logic_vector(C_SR_WIDTH-1 downto 0); |
opb_s_rx_en : out std_logic; |
opb_s_rx_data : in std_logic_vector(C_SR_WIDTH-1 downto 0); |
-- control register |
opb_ctl_reg : out std_logic_vector(C_OPB_CTL_REG_WIDTH-1 downto 0); |
-- Fifo almost full/empty thresholds |
tx_thresh : out std_logic_vector((2*C_FIFO_SIZE_WIDTH)-1 downto 0); |
rx_thresh : out std_logic_vector((2*C_FIFO_SIZE_WIDTH)-1 downto 0); |
opb_fifo_flg : in std_logic_vector(C_NUM_FLG-1 downto 0); |
-- interrupts |
opb_dgie : out std_logic; |
opb_ier : out std_logic_vector(C_NUM_INT-1 downto 0); |
opb_isr : in std_logic_vector(C_NUM_INT-1 downto 0); |
opb_isr_clr : out std_logic_vector(C_NUM_INT-1 downto 0); |
-- dma register |
opb_tx_dma_addr : out std_logic_vector(C_OPB_DWIDTH-1 downto 0); |
opb_tx_dma_ctl : out std_logic_vector(0 downto 0); |
opb_tx_dma_num : out std_logic_vector(C_WIDTH_DMA_NUM-1 downto 0); |
opb_rx_dma_addr : out std_logic_vector(C_OPB_DWIDTH-1 downto 0); |
opb_rx_dma_ctl : out std_logic_vector(0 downto 0); |
opb_rx_dma_num : out std_logic_vector(C_WIDTH_DMA_NUM-1 downto 0); |
-- rx crc |
opb_rx_crc_value : in std_logic_vector(C_SR_WIDTH-1 downto 0); |
opb_tx_crc_value : in std_logic_vector(C_SR_WIDTH-1 downto 0)); |
end opb_if; |
|
architecture behavior of opb_if is |
|
|
signal Sln_DBus_big_end : std_logic_vector(C_OPB_DWIDTH-1 downto 0); |
signal OPB_ABus_big_end : std_logic_vector(C_OPB_DWIDTH-1 downto 0); |
signal OPB_DBus_big_end : std_logic_vector(C_OPB_DWIDTH-1 downto 0); |
|
|
type state_t is (idle, |
done); |
signal state : state_t := idle; |
|
-- internal signals to enable readback |
|
signal tx_thresh_int : std_logic_vector((2*C_FIFO_SIZE_WIDTH)-1 downto 0); |
signal rx_thresh_int : std_logic_vector((2*C_FIFO_SIZE_WIDTH)-1 downto 0); |
signal opb_ier_int : std_logic_vector(C_NUM_INT-1 downto 0); |
signal opb_dgie_int : std_logic; |
|
signal opb_ctl_reg_int : std_logic_vector(C_OPB_CTL_REG_WIDTH-1 downto 0); |
|
|
-- only used if C_DMA_EN=true |
signal opb_tx_dma_addr_int : std_logic_vector(C_OPB_DWIDTH-1 downto 0); |
signal opb_tx_dma_ctl_int : std_logic_vector(0 downto 0); |
signal opb_tx_dma_num_int : std_logic_vector(C_WIDTH_DMA_NUM-1 downto 0); |
signal opb_rx_dma_addr_int : std_logic_vector(C_OPB_DWIDTH-1 downto 0); |
signal opb_rx_dma_ctl_int : std_logic_vector(0 downto 0); |
signal opb_rx_dma_num_int : std_logic_vector(C_WIDTH_DMA_NUM-1 downto 0); |
|
begin -- behavior |
|
tx_thresh <= tx_thresh_int; |
rx_thresh <= rx_thresh_int; |
opb_ier <= opb_ier_int; |
opb_dgie <= opb_dgie_int; |
|
opb_ctl_reg <= opb_ctl_reg_int; |
|
--* Signals for DMA-Engine control |
u1 : if C_DMA_EN generate |
opb_tx_dma_ctl <= opb_tx_dma_ctl_int; |
opb_tx_dma_addr <= opb_tx_dma_addr_int; |
opb_tx_dma_num <= opb_tx_dma_num_int; |
opb_rx_dma_ctl <= opb_rx_dma_ctl_int; |
opb_rx_dma_addr <= opb_rx_dma_addr_int; |
opb_rx_dma_num <= opb_rx_dma_num_int; |
end generate u1; |
|
|
-- unused outputs |
Sln_errAck <= '0'; |
Sln_retry <= '0'; |
Sln_toutSup <= '0'; |
|
--* convert Sln_DBus_big_end to little mode |
conv_big_Sln_DBus_proc : process(Sln_DBus_big_end) |
begin |
for i in 0 to 31 loop |
Sln_DBus(31-i) <= Sln_DBus_big_end(i); |
end loop; -- i |
end process conv_big_Sln_DBus_proc; |
|
--* convert OPB_ABus to big endian |
conv_big_OPB_ABus_proc : process(OPB_ABus) |
begin |
for i in 0 to 31 loop |
OPB_ABus_big_end(31-i) <= OPB_ABus(i); |
end loop; -- i |
end process conv_big_OPB_ABus_proc; |
|
--* convert OPB_DBus to little mode |
conv_big_OPB_DBus_proc : process(OPB_DBus) |
begin |
for i in 0 to 31 loop |
OPB_DBus_big_end(31-i) <= OPB_DBus(i); |
end loop; -- i |
end process conv_big_OPB_DBus_proc; |
|
--* control OPB requests |
--* |
--* handles OPB-read and -write request |
opb_slave_proc : process (OPB_Rst, OPB_Clk) |
begin |
if (OPB_Rst = '1') then |
-- OPB |
Sln_xferAck <= '0'; |
Sln_DBus_big_end <= (others => '0'); |
-- FIFO |
opb_s_rx_en <= '0'; |
opb_s_tx_en <= '0'; |
-- |
state <= idle; |
-- Register |
tx_thresh_int <= (others => '0'); |
rx_thresh_int <= (others => '0'); |
opb_ier_int <= (others => '0'); |
opb_dgie_int <= '0'; |
opb_ctl_reg_int <= (others => '0'); |
|
if C_DMA_EN then |
opb_tx_dma_ctl_int <= (others => '0'); |
opb_tx_dma_addr_int <= (others => '0'); |
opb_tx_dma_num_int <= (others => '0'); |
opb_rx_dma_ctl_int <= (others => '0'); |
opb_rx_dma_addr_int <= (others => '0'); |
opb_rx_dma_num_int <= (others => '0'); |
end if; |
|
|
elsif (OPB_Clk'event and OPB_Clk = '1') then |
case state is |
when idle => |
if (OPB_select = '1' and |
((OPB_ABus >= C_BASEADDR) and (OPB_ABus <= C_HIGHADDR))) then |
-- *device selected |
Sln_xferAck <= '1'; |
state <= done; |
if (OPB_RNW = '1') then |
-- read acess |
case OPB_ABus_big_end(7 downto 2) is |
when C_ADR_CTL => |
Sln_DBus_big_end(C_OPB_CTL_REG_WIDTH-1 downto 0) <= opb_ctl_reg_int; |
|
when C_ADR_RX_DATA => |
opb_s_rx_en <= '1'; |
Sln_DBus_big_end(C_SR_WIDTH-1 downto 0) <= opb_s_rx_data; |
|
when C_ADR_STATUS => |
Sln_DBus_big_end(C_NUM_FLG-1 downto 0) <= opb_fifo_flg; |
|
when C_ADR_TX_THRESH => |
Sln_DBus_big_end(C_FIFO_SIZE_WIDTH-1 downto 0) <= tx_thresh_int(C_FIFO_SIZE_WIDTH-1 downto 0); |
Sln_DBus_big_end(16+C_FIFO_SIZE_WIDTH-1 downto 16) <= tx_thresh_int((2*C_FIFO_SIZE_WIDTH)-1 downto C_FIFO_SIZE_WIDTH); |
|
when C_ADR_RX_THRESH => |
Sln_DBus_big_end(C_FIFO_SIZE_WIDTH-1 downto 0) <= rx_thresh_int(C_FIFO_SIZE_WIDTH-1 downto 0); |
Sln_DBus_big_end(16+C_FIFO_SIZE_WIDTH-1 downto 16) <= rx_thresh_int((2*C_FIFO_SIZE_WIDTH)-1 downto C_FIFO_SIZE_WIDTH); |
|
when C_ADR_DGIE => |
Sln_DBus_big_end(0) <= opb_dgie_int; |
when C_ADR_IER => |
Sln_DBus_big_end(C_NUM_INT-1 downto 0) <= opb_ier_int; |
|
when C_ADR_ISR => |
Sln_DBus_big_end(C_NUM_INT-1 downto 0) <= opb_isr; |
|
when C_ADR_TX_DMA_CTL => |
if C_DMA_EN then |
Sln_DBus_big_end(0 downto 0) <= opb_tx_dma_ctl_int; |
end if; |
|
when C_ADR_TX_DMA_ADDR => |
if C_DMA_EN then |
Sln_DBus_big_end(C_OPB_DWIDTH-1 downto 0) <= opb_tx_dma_addr_int; |
end if; |
|
when C_ADR_TX_DMA_NUM => |
if C_DMA_EN then |
Sln_DBus_big_end(C_WIDTH_DMA_NUM-1 downto 0) <= opb_tx_dma_num_int; |
end if; |
|
|
when C_ADR_RX_DMA_CTL => |
if C_DMA_EN then |
Sln_DBus_big_end(0 downto 0) <= opb_rx_dma_ctl_int; |
end if; |
|
when C_ADR_RX_DMA_ADDR => |
if C_DMA_EN then |
Sln_DBus_big_end(C_OPB_DWIDTH-1 downto 0) <= opb_rx_dma_addr_int; |
end if; |
|
when C_ADR_RX_DMA_NUM => |
if C_DMA_EN then |
Sln_DBus_big_end(C_WIDTH_DMA_NUM-1 downto 0) <= opb_rx_dma_num_int; |
end if; |
|
when C_ADR_RX_CRC => |
if C_CRC_EN then |
Sln_DBus_big_end(C_OPB_DWIDTH-1 downto C_SR_WIDTH) <= (others => '0'); |
Sln_DBus_big_end(C_SR_WIDTH-1 downto 0) <= opb_rx_crc_value; |
end if; |
|
when C_ADR_TX_CRC => |
if C_CRC_EN then |
Sln_DBus_big_end(C_OPB_DWIDTH-1 downto C_SR_WIDTH) <= (others => '0'); |
Sln_DBus_big_end(C_SR_WIDTH-1 downto 0) <= opb_tx_crc_value; |
end if; |
when others => |
null; |
end case; |
else |
-- write acess |
case OPB_ABus_big_end(7 downto 2) is |
when C_ADR_CTL => |
opb_ctl_reg_int <= OPB_DBus_big_end(C_OPB_CTL_REG_WIDTH-1 downto 0); |
|
when C_ADR_TX_DATA => |
opb_s_tx_en <= '1'; |
opb_s_tx_data <= OPB_DBus_big_end(C_SR_WIDTH-1 downto 0); |
|
when C_ADR_TX_THRESH => |
tx_thresh_int(C_FIFO_SIZE_WIDTH-1 downto 0) <= OPB_DBus_big_end(C_FIFO_SIZE_WIDTH-1 downto 0); |
tx_thresh_int((2*C_FIFO_SIZE_WIDTH)-1 downto C_FIFO_SIZE_WIDTH) <= OPB_DBus_big_end(16+C_FIFO_SIZE_WIDTH-1 downto 16); |
|
when C_ADR_RX_THRESH => |
rx_thresh_int(C_FIFO_SIZE_WIDTH-1 downto 0) <= OPB_DBus_big_end(C_FIFO_SIZE_WIDTH-1 downto 0); |
rx_thresh_int((2*C_FIFO_SIZE_WIDTH)-1 downto C_FIFO_SIZE_WIDTH) <= OPB_DBus_big_end(16+C_FIFO_SIZE_WIDTH-1 downto 16); |
|
when C_ADR_DGIE => |
opb_dgie_int <= OPB_DBus_big_end(0); |
|
when C_ADR_IER => |
opb_ier_int <= OPB_DBus_big_end(C_NUM_INT-1 downto 0); |
|
when C_ADR_ISR => |
opb_isr_clr <= OPB_DBus_big_end(C_NUM_INT-1 downto 0); |
|
when C_ADR_TX_DMA_CTL => |
if C_DMA_EN then |
opb_tx_dma_ctl_int <= OPB_DBus_big_end(0 downto 0); |
end if; |
|
when C_ADR_TX_DMA_ADDR => |
if C_DMA_EN then |
opb_tx_dma_addr_int <= OPB_DBus_big_end(C_OPB_DWIDTH-1 downto 0); |
end if; |
|
when C_ADR_TX_DMA_NUM => |
if C_DMA_EN then |
opb_tx_dma_num_int <= OPB_DBus_big_end(C_WIDTH_DMA_NUM-1 downto 0); |
end if; |
|
when C_ADR_RX_DMA_CTL => |
if C_DMA_EN then |
opb_rx_dma_ctl_int <= OPB_DBus_big_end(0 downto 0); |
end if; |
|
when C_ADR_RX_DMA_ADDR => |
if C_DMA_EN then |
opb_rx_dma_addr_int <= OPB_DBus_big_end(C_OPB_DWIDTH-1 downto 0); |
end if; |
|
when C_ADR_RX_DMA_NUM => |
if C_DMA_EN then |
opb_rx_dma_num_int <= OPB_DBus_big_end(C_WIDTH_DMA_NUM-1 downto 0); |
end if; |
|
when others => |
null; |
end case; |
end if; -- OPB_RNW |
else |
-- not selected |
state <= idle; |
end if; |
when done => |
opb_ctl_reg_int(3) <= '0'; |
opb_isr_clr <= (others => '0'); |
opb_s_rx_en <= '0'; |
opb_s_tx_en <= '0'; |
Sln_xferAck <= '0'; |
Sln_DBus_big_end <= (others => '0'); |
state <= idle; |
|
when others => |
state <= idle; |
end case; |
end if; |
end process opb_slave_proc; |
end behavior; |
/opb_m_if.vhd
0,0 → 1,320
------------------------------------------------------------------------------- |
--* |
--* @short OPB-Master Interface |
--* |
--* Generics described in top entity. |
--* |
--* @see opb_spi_slave |
|
--* @version: 1.0 |
--* @date: 2007-11-11 |
--/ |
------------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
use IEEE.STD_LOGIC_ARITH.all; |
use IEEE.STD_LOGIC_UNSIGNED.all; |
use IEEE.numeric_std.all; -- conv_integer() |
|
library work; |
use work.opb_spi_slave_pack.all; |
|
entity opb_m_if is |
generic ( |
C_BASEADDR : std_logic_vector(0 to 31) := X"00000000"; |
C_HIGHADDR : std_logic_vector(0 to 31) := X"FFFFFFFF"; |
C_USER_ID_CODE : integer := 0; |
C_OPB_AWIDTH : integer := 32; |
C_OPB_DWIDTH : integer := 32; |
C_FAMILY : string := "virtex-4"; |
C_SR_WIDTH : integer := 8; |
C_MSB_FIRST : boolean := true; |
C_CPOL : integer range 0 to 1 := 0; |
C_PHA : integer range 0 to 1 := 0; |
C_FIFO_SIZE_WIDTH : integer range 4 to 7 := 7); |
|
port ( |
-- opb master interface |
OPB_Clk : in std_logic; |
OPB_Rst : in std_logic; |
OPB_DBus : in std_logic_vector(0 to C_OPB_DWIDTH-1); |
M_request : out std_logic; |
MOPB_MGrant : in std_logic; |
M_busLock : out std_logic; |
M_ABus : out std_logic_vector(0 to C_OPB_AWIDTH-1); |
M_BE : out std_logic_vector(0 to C_OPB_DWIDTH/8-1); |
M_DBus : out std_logic_vector(0 to C_OPB_DWIDTH-1); |
M_RNW : out std_logic; |
M_select : out std_logic; |
M_seqAddr : out std_logic; |
MOPB_errAck : in std_logic; |
MOPB_retry : in std_logic; |
MOPB_timeout : in std_logic; |
MOPB_xferAck : in std_logic; |
--------------------------------------------------------------------------- |
-- read transfer |
-- read data from memory and fill fifo |
opb_m_tx_req : in std_logic; |
opb_m_tx_en : out std_logic; |
opb_m_tx_data : out std_logic_vector(C_SR_WIDTH-1 downto 0); |
-- enable/disable dma transfer |
opb_tx_dma_ctl : in std_logic_vector(0 downto 0); |
-- base adress for transfer |
opb_tx_dma_addr : in std_logic_vector(C_OPB_DWIDTH-1 downto 0); |
opb_tx_dma_num : in std_logic_vector(C_WIDTH_DMA_NUM-1 downto 0); |
opb_tx_dma_done : out std_logic; |
--------------------------------------------------------------------------- |
-- write transfer |
-- read fifo an write to memory |
opb_m_rx_req : in std_logic; |
opb_m_rx_en : out std_logic; |
opb_m_rx_data : in std_logic_vector(C_SR_WIDTH-1 downto 0); |
-- enable/disable dma transfer |
opb_rx_dma_ctl : in std_logic_vector(0 downto 0); |
-- base adress for transfer |
opb_rx_dma_addr : in std_logic_vector(C_OPB_DWIDTH-1 downto 0); |
opb_rx_dma_num : in std_logic_vector(C_WIDTH_DMA_NUM-1 downto 0); |
opb_rx_dma_done : out std_logic; |
--------------------------------------------------------------------------- |
opb_abort_flg : out std_logic; |
opb_m_last_block : out std_logic); |
end opb_m_if; |
|
architecture behavior of opb_m_if is |
|
type state_t is (idle, |
wait_grant, |
transfer_write, |
transfer_read, |
done); |
|
|
signal state : state_t := idle; |
|
signal M_DBus_big_end : std_logic_vector(C_OPB_DWIDTH-1 downto 0); |
signal M_ABus_big_end : std_logic_vector(C_OPB_DWIDTH-1 downto 0); |
signal OPB_DBus_big_end : std_logic_vector(C_OPB_DWIDTH-1 downto 0); |
|
signal M_select_int : std_logic; |
signal read_transfer : boolean; |
|
-- read transfer |
signal opb_tx_dma_addr_int : std_logic_vector(C_OPB_DWIDTH-1 downto 0); |
signal opb_tx_dma_en : std_logic; |
signal opb_tx_dma_num_int : std_logic_vector(C_WIDTH_DMA_NUM-1 downto 0); |
signal opb_tx_dma_done_int : std_logic; |
|
-- write transfer |
signal opb_rx_dma_en : std_logic; |
signal opb_rx_dma_addr_int : std_logic_vector(C_OPB_DWIDTH-1 downto 0); |
signal opb_rx_dma_num_int : std_logic_vector(C_WIDTH_DMA_NUM-1 downto 0); |
signal opb_rx_dma_done_int : std_logic; |
|
|
begin -- behavior |
|
--* convert M_DBus_big_end to little endian |
process(M_DBus_big_end) |
begin |
for i in 0 to 31 loop |
M_DBus(31-i) <= M_DBus_big_end(i); |
end loop; -- i |
end process; |
|
--* convert M_ABus_big_end to little endian |
process(M_ABus_big_end) |
begin |
for i in 0 to 31 loop |
M_ABus(31-i) <= M_ABus_big_end(i); |
end loop; -- i |
end process; |
|
--* convert OPB_DBus to bi endian |
process(OPB_DBus) |
begin |
for i in 0 to 31 loop |
OPB_DBus_big_end(31-i) <= OPB_DBus(i); |
end loop; -- i |
end process; |
|
-- for both sides |
M_ABus_big_end <= opb_tx_dma_addr_int when (M_select_int = '1' and (read_transfer = true)) else |
opb_rx_dma_addr_int when (M_select_int = '1' and (read_transfer = false)) else |
(others => '0'); |
M_select <= M_select_int; |
|
|
|
-- write transfer |
opb_m_rx_en <= MOPB_xferAck when (M_select_int = '1' and (read_transfer = false)) else |
'0'; |
|
M_DBus_big_end(C_SR_WIDTH-1 downto 0) <= opb_m_rx_data when (M_select_int = '1' and (read_transfer = false)) else |
(others => '0'); |
M_DBus_big_end(C_OPB_DWIDTH-1 downto C_SR_WIDTH) <= (others => '0'); |
|
opb_tx_dma_done <= opb_tx_dma_done_int; |
|
-- read transfer |
opb_m_tx_en <= MOPB_xferAck when (M_select_int = '1' and (read_transfer = true)) else |
'0'; |
opb_m_tx_data <= OPB_DBus_big_end(C_SR_WIDTH-1 downto 0); |
|
opb_rx_dma_done <= opb_rx_dma_done_int; |
|
|
|
------------------------------------------------------------------------------- |
opb_masteer_proc : process(OPB_Rst, OPB_Clk) |
begin |
if (OPB_Rst = '1') then |
M_BE <= (others => '0'); |
M_busLock <= '0'; |
M_request <= '0'; |
M_RNW <= '0'; |
M_select_int <= '0'; |
M_seqAddr <= '0'; |
opb_tx_dma_done_int <= '0'; |
opb_rx_dma_done_int <= '0'; |
opb_abort_flg <= '0'; |
opb_m_last_block <= '0'; |
opb_tx_dma_num_int <= (others => '0'); |
opb_rx_dma_num_int <= (others => '0'); |
elsif rising_edge(OPB_Clk) then |
case state is |
when idle => |
opb_abort_flg <= '0'; |
opb_tx_dma_en <= opb_tx_dma_ctl(0); |
opb_rx_dma_en <= opb_rx_dma_ctl(0); |
|
if (opb_tx_dma_ctl(0) = '1' and opb_tx_dma_en = '0') then |
opb_tx_dma_addr_int <= opb_tx_dma_addr; |
opb_tx_dma_num_int <= opb_tx_dma_num; |
opb_tx_dma_done_int <= '0'; |
|
end if; |
|
if (opb_rx_dma_ctl(0) = '1' and opb_rx_dma_en = '0') then |
opb_rx_dma_addr_int <= opb_rx_dma_addr; |
opb_rx_dma_num_int <= opb_rx_dma_num; |
opb_rx_dma_done_int <= '0'; |
end if; |
|
if (opb_tx_dma_en = '1' and opb_m_tx_req = '1' and opb_tx_dma_done_int = '0') then |
-- read from memory to fifo |
M_request <= '1'; |
read_transfer <= true; |
state <= wait_grant; |
elsif (opb_rx_dma_en = '1' and opb_m_rx_req = '1'and opb_rx_dma_done_int = '0') then |
-- read from fifo and write memory |
M_request <= '1'; |
read_transfer <= false; |
state <= wait_grant; |
else |
state <= idle; |
end if; |
|
when wait_grant => |
if (MOPB_MGrant = '1') then |
M_request <= '0'; |
M_busLock <= '1'; |
M_select_int <= '1'; |
M_seqAddr <= '1'; |
M_BE <= "1111"; |
if (read_transfer) then |
-- read |
M_RNW <= '1'; |
if (conv_integer(opb_tx_dma_num_int) = 0) then |
opb_m_last_block <= '1'; |
end if; |
state <= transfer_read; |
else |
-- write |
M_RNW <= '0'; |
if (conv_integer(opb_rx_dma_num_int) = 0) then |
opb_m_last_block <= '1'; |
end if; |
state <= transfer_write; |
end if; |
else |
state <= wait_grant; |
end if; |
|
when transfer_read => |
if (MOPB_xferAck = '1') then |
opb_tx_dma_addr_int <= opb_tx_dma_addr_int +4; |
if (opb_tx_dma_addr_int(5 downto 2) = conv_std_logic_vector(14, 4)) then |
-- cycle 14 |
-- deassert buslock and seq_address 1 cycle before transfer complete |
M_busLock <= '0'; |
M_seqAddr <= '0'; |
elsif (opb_tx_dma_addr_int(5 downto 2) = conv_std_logic_vector(15, 4)) then |
-- cycle 15 |
M_RNW <= '0'; |
M_select_int <= '0'; |
M_BE <= (others => '0'); |
if (conv_integer(opb_tx_dma_num_int) = 0) then |
opb_tx_dma_done_int <= '1'; |
opb_m_last_block <= '0'; |
else |
opb_tx_dma_num_int <= opb_tx_dma_num_int-1; |
end if; |
state <= done; |
end if; |
elsif (MOPB_retry = '1' or MOPB_errAck = '1' or MOPB_timeout = '1') then |
-- cancel transfer |
M_busLock <= '0'; |
M_seqAddr <= '0'; |
M_RNW <= '0'; |
M_select_int <= '0'; |
M_BE <= (others => '0'); |
opb_abort_flg <= '1'; |
state <= done; |
else |
state <= transfer_read; |
end if; |
|
when transfer_write => |
if (MOPB_xferAck = '1') then |
opb_rx_dma_addr_int <= opb_rx_dma_addr_int +4; |
if (opb_rx_dma_addr_int(5 downto 2) = conv_std_logic_vector(14, 4)) then |
-- cycle 14 |
-- deassert buslock and seq_address 1 cycle before transfer complete |
M_busLock <= '0'; |
M_seqAddr <= '0'; |
elsif (opb_rx_dma_addr_int(5 downto 2) = conv_std_logic_vector(15, 4)) then |
-- cycle 15 |
M_RNW <= '0'; |
M_select_int <= '0'; |
M_BE <= (others => '0'); |
if (conv_integer(opb_rx_dma_num_int) = 0) then |
opb_rx_dma_done_int <= '1'; |
opb_m_last_block <= '0'; |
else |
opb_rx_dma_num_int <= opb_rx_dma_num_int-1; |
end if; |
state <= done; |
end if; |
elsif (MOPB_retry = '1' or MOPB_errAck = '1' or MOPB_timeout = '1') then |
-- cancel transfer |
M_busLock <= '0'; |
M_seqAddr <= '0'; |
M_RNW <= '0'; |
M_select_int <= '0'; |
M_BE <= (others => '0'); |
opb_abort_flg <= '1'; |
state <= done; |
else |
state <= transfer_write; |
end if; |
|
when done => |
|
state <= idle; |
|
when others => |
state <= idle; |
end case; |
end if; |
end process opb_masteer_proc; |
end behavior; |
/opb_spi_slave_pack.vhd
0,0 → 1,73
library ieee; |
use ieee.std_logic_1164.all; |
use IEEE.STD_LOGIC_ARITH.all; |
use IEEE.STD_LOGIC_UNSIGNED.all; |
use IEEE.numeric_std.all; -- conv_integer() |
|
package opb_spi_slave_pack is |
|
constant C_ADR_CTL : std_logic_vector(7 downto 2) := conv_std_logic_vector(16#0#, 6); |
constant C_ADR_STATUS : std_logic_vector(7 downto 2) := conv_std_logic_vector(16#1#, 6); |
constant C_ADR_TX_DATA : std_logic_vector(7 downto 2) := conv_std_logic_vector(16#2#, 6); |
constant C_ADR_RX_DATA : std_logic_vector(7 downto 2) := conv_std_logic_vector(16#3#, 6); |
constant C_ADR_TX_THRESH : std_logic_vector(7 downto 2) := conv_std_logic_vector(16#4#, 6); |
constant C_ADR_RX_THRESH : std_logic_vector(7 downto 2) := conv_std_logic_vector(16#5#, 6); |
constant C_ADR_TX_DMA_CTL : std_logic_vector(7 downto 2) := conv_std_logic_vector(16#6#, 6); |
constant C_ADR_TX_DMA_ADDR : std_logic_vector(7 downto 2) := conv_std_logic_vector(16#7#, 6); |
constant C_ADR_TX_DMA_NUM : std_logic_vector(7 downto 2) := conv_std_logic_vector(16#8#, 6); |
constant C_ADR_RX_DMA_CTL : std_logic_vector(7 downto 2) := conv_std_logic_vector(16#9#, 6); |
constant C_ADR_RX_DMA_ADDR : std_logic_vector(7 downto 2) := conv_std_logic_vector(16#A#, 6); |
constant C_ADR_RX_DMA_NUM : std_logic_vector(7 downto 2) := conv_std_logic_vector(16#B#, 6); |
constant C_ADR_RX_CRC : std_logic_vector(7 downto 2) := conv_std_logic_vector(16#C#, 6); |
constant C_ADR_TX_CRC : std_logic_vector(7 downto 2) := conv_std_logic_vector(16#D#, 6); |
|
-- XIIF_V123B compatible |
constant C_ADR_DGIE : std_logic_vector(7 downto 2) := conv_std_logic_vector(16#10#, 6); |
constant C_ADR_ISR : std_logic_vector(7 downto 2) := conv_std_logic_vector(16#11#, 6); |
constant C_ADR_IER : std_logic_vector(7 downto 2) := conv_std_logic_vector(16#12#, 6); |
|
constant C_NUM_FLG : integer := 16; |
constant C_NUM_INT : integer := 11; |
constant C_WIDTH_DMA_NUM : integer := 24; |
|
|
-- CTL_Register |
-- width |
constant C_OPB_CTL_REG_WIDTH : integer := 6; |
-- bits |
constant C_OPB_CTL_REG_DGE : integer := 0; |
constant C_OPB_CTL_REG_TX_EN : integer := 1; |
constant C_OPB_CTL_REG_RX_EN : integer := 2; |
constant C_OPB_CTL_REG_RST : integer := 3; |
constant C_OPB_CTL_REG_CRC_EN : integer := 4; |
constant C_OPB_CTL_REG_CRC_CLR : integer := 5; |
|
-- Status Register |
constant SPI_SR_Bit_TX_Prog_Full : integer := 0; |
constant SPI_SR_Bit_TX_Full : integer := 1; |
constant SPI_SR_Bit_TX_Overflow : integer := 2; |
constant SPI_SR_Bit_TX_Prog_empty : integer := 3; |
constant SPI_SR_Bit_TX_Empty : integer := 4; |
constant SPI_SR_Bit_TX_Underflow : integer := 5; |
|
constant SPI_SR_Bit_RX_Prog_Full : integer := 6; |
constant SPI_SR_Bit_RX_Full : integer := 7; |
constant SPI_SR_Bit_RX_Overflow : integer := 8; |
constant SPI_SR_Bit_RX_Prog_empty : integer := 9; |
constant SPI_SR_Bit_RX_Empty : integer := 10; |
constant SPI_SR_Bit_RX_Underflow : integer := 11; |
|
constant SPI_SR_Bit_SS_n : integer := 12; |
constant SPI_SR_Bit_TX_DMA_Done : integer := 13; |
constant SPI_SR_Bit_RX_DMA_Done : integer := 14; |
|
-- Interrupt Status Register |
constant SPI_ISR_Bit_TX_Prog_Empty : integer := 0; |
constant SPI_ISR_Bit_TX_Empty : integer := 1; |
constant SPI_ISR_Bit_TX_Underflow : integer := 2; |
constant SPI_ISR_Bit_RX_Prog_Full : integer := 3; |
constant SPI_ISR_Bit_RX_Full : integer := 4; |
constant SPI_ISR_Bit_RX_Overflow : integer := 5; |
constant SPI_ISR_Bit_SS_Fall : integer := 6; |
constant SPI_ISR_Bit_SS_Rise : integer := 7; |
end opb_spi_slave_pack; |
/PCK_CRC32_D32.vhd
0,0 → 1,229
----------------------------------------------------------------------- |
-- File: PCK_CRC32_D32.vhd |
-- Date: Tue Mar 4 19:11:40 2008 |
-- |
-- Copyright (C) 1999-2003 Easics NV. |
-- This source file may be used and distributed without restriction |
-- provided that this copyright statement is not removed from the file |
-- and that any derivative work contains the original copyright notice |
-- and the associated disclaimer. |
-- |
-- THIS SOURCE FILE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS |
-- OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED |
-- WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
-- |
-- Purpose: VHDL package containing a synthesizable CRC function |
-- * polynomial: (0 1 2 4 5 7 8 10 11 12 16 22 23 26 32) |
-- * data width: 32 |
-- |
-- Info: tools@easics.be |
-- http://www.easics.com |
----------------------------------------------------------------------- |
|
|
library IEEE; |
use IEEE.std_logic_1164.all; |
|
package PCK_CRC32_D32 is |
|
-- polynomial: (0 1 2 4 5 7 8 10 11 12 16 22 23 26 32) |
-- data width: 32 |
-- convention: the first serial data bit is D(31) |
function nextCRC32_D32 |
( Data: std_logic_vector(31 downto 0); |
CRC: std_logic_vector(31 downto 0) ) |
return std_logic_vector; |
|
end PCK_CRC32_D32; |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
|
package body PCK_CRC32_D32 is |
|
-- polynomial: (0 1 2 4 5 7 8 10 11 12 16 22 23 26 32) |
-- data width: 32 |
-- convention: the first serial data bit is D(31) |
function nextCRC32_D32 |
( Data: std_logic_vector(31 downto 0); |
CRC: std_logic_vector(31 downto 0) ) |
return std_logic_vector is |
|
variable D: std_logic_vector(31 downto 0); |
variable C: std_logic_vector(31 downto 0); |
variable NewCRC: std_logic_vector(31 downto 0); |
|
begin |
|
D := Data; |
C := CRC; |
|
NewCRC(0) := D(31) xor D(30) xor D(29) xor D(28) xor D(26) xor D(25) xor |
D(24) xor D(16) xor D(12) xor D(10) xor D(9) xor D(6) xor |
D(0) xor C(0) xor C(6) xor C(9) xor C(10) xor C(12) xor |
C(16) xor C(24) xor C(25) xor C(26) xor C(28) xor C(29) xor |
C(30) xor C(31); |
NewCRC(1) := D(28) xor D(27) xor D(24) xor D(17) xor D(16) xor D(13) xor |
D(12) xor D(11) xor D(9) xor D(7) xor D(6) xor D(1) xor |
D(0) xor C(0) xor C(1) xor C(6) xor C(7) xor C(9) xor |
C(11) xor C(12) xor C(13) xor C(16) xor C(17) xor C(24) xor |
C(27) xor C(28); |
NewCRC(2) := D(31) xor D(30) xor D(26) xor D(24) xor D(18) xor D(17) xor |
D(16) xor D(14) xor D(13) xor D(9) xor D(8) xor D(7) xor |
D(6) xor D(2) xor D(1) xor D(0) xor C(0) xor C(1) xor |
C(2) xor C(6) xor C(7) xor C(8) xor C(9) xor C(13) xor |
C(14) xor C(16) xor C(17) xor C(18) xor C(24) xor C(26) xor |
C(30) xor C(31); |
NewCRC(3) := D(31) xor D(27) xor D(25) xor D(19) xor D(18) xor D(17) xor |
D(15) xor D(14) xor D(10) xor D(9) xor D(8) xor D(7) xor |
D(3) xor D(2) xor D(1) xor C(1) xor C(2) xor C(3) xor |
C(7) xor C(8) xor C(9) xor C(10) xor C(14) xor C(15) xor |
C(17) xor C(18) xor C(19) xor C(25) xor C(27) xor C(31); |
NewCRC(4) := D(31) xor D(30) xor D(29) xor D(25) xor D(24) xor D(20) xor |
D(19) xor D(18) xor D(15) xor D(12) xor D(11) xor D(8) xor |
D(6) xor D(4) xor D(3) xor D(2) xor D(0) xor C(0) xor |
C(2) xor C(3) xor C(4) xor C(6) xor C(8) xor C(11) xor |
C(12) xor C(15) xor C(18) xor C(19) xor C(20) xor C(24) xor |
C(25) xor C(29) xor C(30) xor C(31); |
NewCRC(5) := D(29) xor D(28) xor D(24) xor D(21) xor D(20) xor D(19) xor |
D(13) xor D(10) xor D(7) xor D(6) xor D(5) xor D(4) xor |
D(3) xor D(1) xor D(0) xor C(0) xor C(1) xor C(3) xor |
C(4) xor C(5) xor C(6) xor C(7) xor C(10) xor C(13) xor |
C(19) xor C(20) xor C(21) xor C(24) xor C(28) xor C(29); |
NewCRC(6) := D(30) xor D(29) xor D(25) xor D(22) xor D(21) xor D(20) xor |
D(14) xor D(11) xor D(8) xor D(7) xor D(6) xor D(5) xor |
D(4) xor D(2) xor D(1) xor C(1) xor C(2) xor C(4) xor |
C(5) xor C(6) xor C(7) xor C(8) xor C(11) xor C(14) xor |
C(20) xor C(21) xor C(22) xor C(25) xor C(29) xor C(30); |
NewCRC(7) := D(29) xor D(28) xor D(25) xor D(24) xor D(23) xor D(22) xor |
D(21) xor D(16) xor D(15) xor D(10) xor D(8) xor D(7) xor |
D(5) xor D(3) xor D(2) xor D(0) xor C(0) xor C(2) xor |
C(3) xor C(5) xor C(7) xor C(8) xor C(10) xor C(15) xor |
C(16) xor C(21) xor C(22) xor C(23) xor C(24) xor C(25) xor |
C(28) xor C(29); |
NewCRC(8) := D(31) xor D(28) xor D(23) xor D(22) xor D(17) xor D(12) xor |
D(11) xor D(10) xor D(8) xor D(4) xor D(3) xor D(1) xor |
D(0) xor C(0) xor C(1) xor C(3) xor C(4) xor C(8) xor |
C(10) xor C(11) xor C(12) xor C(17) xor C(22) xor C(23) xor |
C(28) xor C(31); |
NewCRC(9) := D(29) xor D(24) xor D(23) xor D(18) xor D(13) xor D(12) xor |
D(11) xor D(9) xor D(5) xor D(4) xor D(2) xor D(1) xor |
C(1) xor C(2) xor C(4) xor C(5) xor C(9) xor C(11) xor |
C(12) xor C(13) xor C(18) xor C(23) xor C(24) xor C(29); |
NewCRC(10) := D(31) xor D(29) xor D(28) xor D(26) xor D(19) xor D(16) xor |
D(14) xor D(13) xor D(9) xor D(5) xor D(3) xor D(2) xor |
D(0) xor C(0) xor C(2) xor C(3) xor C(5) xor C(9) xor |
C(13) xor C(14) xor C(16) xor C(19) xor C(26) xor C(28) xor |
C(29) xor C(31); |
NewCRC(11) := D(31) xor D(28) xor D(27) xor D(26) xor D(25) xor D(24) xor |
D(20) xor D(17) xor D(16) xor D(15) xor D(14) xor D(12) xor |
D(9) xor D(4) xor D(3) xor D(1) xor D(0) xor C(0) xor |
C(1) xor C(3) xor C(4) xor C(9) xor C(12) xor C(14) xor |
C(15) xor C(16) xor C(17) xor C(20) xor C(24) xor C(25) xor |
C(26) xor C(27) xor C(28) xor C(31); |
NewCRC(12) := D(31) xor D(30) xor D(27) xor D(24) xor D(21) xor D(18) xor |
D(17) xor D(15) xor D(13) xor D(12) xor D(9) xor D(6) xor |
D(5) xor D(4) xor D(2) xor D(1) xor D(0) xor C(0) xor |
C(1) xor C(2) xor C(4) xor C(5) xor C(6) xor C(9) xor |
C(12) xor C(13) xor C(15) xor C(17) xor C(18) xor C(21) xor |
C(24) xor C(27) xor C(30) xor C(31); |
NewCRC(13) := D(31) xor D(28) xor D(25) xor D(22) xor D(19) xor D(18) xor |
D(16) xor D(14) xor D(13) xor D(10) xor D(7) xor D(6) xor |
D(5) xor D(3) xor D(2) xor D(1) xor C(1) xor C(2) xor |
C(3) xor C(5) xor C(6) xor C(7) xor C(10) xor C(13) xor |
C(14) xor C(16) xor C(18) xor C(19) xor C(22) xor C(25) xor |
C(28) xor C(31); |
NewCRC(14) := D(29) xor D(26) xor D(23) xor D(20) xor D(19) xor D(17) xor |
D(15) xor D(14) xor D(11) xor D(8) xor D(7) xor D(6) xor |
D(4) xor D(3) xor D(2) xor C(2) xor C(3) xor C(4) xor |
C(6) xor C(7) xor C(8) xor C(11) xor C(14) xor C(15) xor |
C(17) xor C(19) xor C(20) xor C(23) xor C(26) xor C(29); |
NewCRC(15) := D(30) xor D(27) xor D(24) xor D(21) xor D(20) xor D(18) xor |
D(16) xor D(15) xor D(12) xor D(9) xor D(8) xor D(7) xor |
D(5) xor D(4) xor D(3) xor C(3) xor C(4) xor C(5) xor |
C(7) xor C(8) xor C(9) xor C(12) xor C(15) xor C(16) xor |
C(18) xor C(20) xor C(21) xor C(24) xor C(27) xor C(30); |
NewCRC(16) := D(30) xor D(29) xor D(26) xor D(24) xor D(22) xor D(21) xor |
D(19) xor D(17) xor D(13) xor D(12) xor D(8) xor D(5) xor |
D(4) xor D(0) xor C(0) xor C(4) xor C(5) xor C(8) xor |
C(12) xor C(13) xor C(17) xor C(19) xor C(21) xor C(22) xor |
C(24) xor C(26) xor C(29) xor C(30); |
NewCRC(17) := D(31) xor D(30) xor D(27) xor D(25) xor D(23) xor D(22) xor |
D(20) xor D(18) xor D(14) xor D(13) xor D(9) xor D(6) xor |
D(5) xor D(1) xor C(1) xor C(5) xor C(6) xor C(9) xor |
C(13) xor C(14) xor C(18) xor C(20) xor C(22) xor C(23) xor |
C(25) xor C(27) xor C(30) xor C(31); |
NewCRC(18) := D(31) xor D(28) xor D(26) xor D(24) xor D(23) xor D(21) xor |
D(19) xor D(15) xor D(14) xor D(10) xor D(7) xor D(6) xor |
D(2) xor C(2) xor C(6) xor C(7) xor C(10) xor C(14) xor |
C(15) xor C(19) xor C(21) xor C(23) xor C(24) xor C(26) xor |
C(28) xor C(31); |
NewCRC(19) := D(29) xor D(27) xor D(25) xor D(24) xor D(22) xor D(20) xor |
D(16) xor D(15) xor D(11) xor D(8) xor D(7) xor D(3) xor |
C(3) xor C(7) xor C(8) xor C(11) xor C(15) xor C(16) xor |
C(20) xor C(22) xor C(24) xor C(25) xor C(27) xor C(29); |
NewCRC(20) := D(30) xor D(28) xor D(26) xor D(25) xor D(23) xor D(21) xor |
D(17) xor D(16) xor D(12) xor D(9) xor D(8) xor D(4) xor |
C(4) xor C(8) xor C(9) xor C(12) xor C(16) xor C(17) xor |
C(21) xor C(23) xor C(25) xor C(26) xor C(28) xor C(30); |
NewCRC(21) := D(31) xor D(29) xor D(27) xor D(26) xor D(24) xor D(22) xor |
D(18) xor D(17) xor D(13) xor D(10) xor D(9) xor D(5) xor |
C(5) xor C(9) xor C(10) xor C(13) xor C(17) xor C(18) xor |
C(22) xor C(24) xor C(26) xor C(27) xor C(29) xor C(31); |
NewCRC(22) := D(31) xor D(29) xor D(27) xor D(26) xor D(24) xor D(23) xor |
D(19) xor D(18) xor D(16) xor D(14) xor D(12) xor D(11) xor |
D(9) xor D(0) xor C(0) xor C(9) xor C(11) xor C(12) xor |
C(14) xor C(16) xor C(18) xor C(19) xor C(23) xor C(24) xor |
C(26) xor C(27) xor C(29) xor C(31); |
NewCRC(23) := D(31) xor D(29) xor D(27) xor D(26) xor D(20) xor D(19) xor |
D(17) xor D(16) xor D(15) xor D(13) xor D(9) xor D(6) xor |
D(1) xor D(0) xor C(0) xor C(1) xor C(6) xor C(9) xor |
C(13) xor C(15) xor C(16) xor C(17) xor C(19) xor C(20) xor |
C(26) xor C(27) xor C(29) xor C(31); |
NewCRC(24) := D(30) xor D(28) xor D(27) xor D(21) xor D(20) xor D(18) xor |
D(17) xor D(16) xor D(14) xor D(10) xor D(7) xor D(2) xor |
D(1) xor C(1) xor C(2) xor C(7) xor C(10) xor C(14) xor |
C(16) xor C(17) xor C(18) xor C(20) xor C(21) xor C(27) xor |
C(28) xor C(30); |
NewCRC(25) := D(31) xor D(29) xor D(28) xor D(22) xor D(21) xor D(19) xor |
D(18) xor D(17) xor D(15) xor D(11) xor D(8) xor D(3) xor |
D(2) xor C(2) xor C(3) xor C(8) xor C(11) xor C(15) xor |
C(17) xor C(18) xor C(19) xor C(21) xor C(22) xor C(28) xor |
C(29) xor C(31); |
NewCRC(26) := D(31) xor D(28) xor D(26) xor D(25) xor D(24) xor D(23) xor |
D(22) xor D(20) xor D(19) xor D(18) xor D(10) xor D(6) xor |
D(4) xor D(3) xor D(0) xor C(0) xor C(3) xor C(4) xor |
C(6) xor C(10) xor C(18) xor C(19) xor C(20) xor C(22) xor |
C(23) xor C(24) xor C(25) xor C(26) xor C(28) xor C(31); |
NewCRC(27) := D(29) xor D(27) xor D(26) xor D(25) xor D(24) xor D(23) xor |
D(21) xor D(20) xor D(19) xor D(11) xor D(7) xor D(5) xor |
D(4) xor D(1) xor C(1) xor C(4) xor C(5) xor C(7) xor |
C(11) xor C(19) xor C(20) xor C(21) xor C(23) xor C(24) xor |
C(25) xor C(26) xor C(27) xor C(29); |
NewCRC(28) := D(30) xor D(28) xor D(27) xor D(26) xor D(25) xor D(24) xor |
D(22) xor D(21) xor D(20) xor D(12) xor D(8) xor D(6) xor |
D(5) xor D(2) xor C(2) xor C(5) xor C(6) xor C(8) xor |
C(12) xor C(20) xor C(21) xor C(22) xor C(24) xor C(25) xor |
C(26) xor C(27) xor C(28) xor C(30); |
NewCRC(29) := D(31) xor D(29) xor D(28) xor D(27) xor D(26) xor D(25) xor |
D(23) xor D(22) xor D(21) xor D(13) xor D(9) xor D(7) xor |
D(6) xor D(3) xor C(3) xor C(6) xor C(7) xor C(9) xor |
C(13) xor C(21) xor C(22) xor C(23) xor C(25) xor C(26) xor |
C(27) xor C(28) xor C(29) xor C(31); |
NewCRC(30) := D(30) xor D(29) xor D(28) xor D(27) xor D(26) xor D(24) xor |
D(23) xor D(22) xor D(14) xor D(10) xor D(8) xor D(7) xor |
D(4) xor C(4) xor C(7) xor C(8) xor C(10) xor C(14) xor |
C(22) xor C(23) xor C(24) xor C(26) xor C(27) xor C(28) xor |
C(29) xor C(30); |
NewCRC(31) := D(31) xor D(30) xor D(29) xor D(28) xor D(27) xor D(25) xor |
D(24) xor D(23) xor D(15) xor D(11) xor D(9) xor D(8) xor |
D(5) xor C(5) xor C(8) xor C(9) xor C(11) xor C(15) xor |
C(23) xor C(24) xor C(25) xor C(27) xor C(28) xor C(29) xor |
C(30) xor C(31); |
|
return NewCRC; |
|
end nextCRC32_D32; |
|
end PCK_CRC32_D32; |
|
/PCK_CRC8_D8.vhd
0,0 → 1,77
----------------------------------------------------------------------- |
-- File: PCK_CRC8_D8.vhd |
-- Date: Fri Mar 21 22:28:05 2008 |
-- |
-- Copyright (C) 1999-2003 Easics NV. |
-- This source file may be used and distributed without restriction |
-- provided that this copyright statement is not removed from the file |
-- and that any derivative work contains the original copyright notice |
-- and the associated disclaimer. |
-- |
-- THIS SOURCE FILE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS |
-- OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED |
-- WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
-- |
-- Purpose: VHDL package containing a synthesizable CRC function |
-- * polynomial: (0 1 2 8) |
-- * data width: 8 |
-- |
-- Info: tools@easics.be |
-- http://www.easics.com |
----------------------------------------------------------------------- |
|
|
library IEEE; |
use IEEE.std_logic_1164.all; |
|
package PCK_CRC8_D8 is |
|
-- polynomial: (0 1 2 8) |
-- data width: 8 |
-- convention: the first serial data bit is D(7) |
function nextCRC8_D8 |
( Data: std_logic_vector(7 downto 0); |
CRC: std_logic_vector(7 downto 0) ) |
return std_logic_vector; |
|
end PCK_CRC8_D8; |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
|
package body PCK_CRC8_D8 is |
|
-- polynomial: (0 1 2 8) |
-- data width: 8 |
-- convention: the first serial data bit is D(7) |
function nextCRC8_D8 |
( Data: std_logic_vector(7 downto 0); |
CRC: std_logic_vector(7 downto 0) ) |
return std_logic_vector is |
|
variable D: std_logic_vector(7 downto 0); |
variable C: std_logic_vector(7 downto 0); |
variable NewCRC: std_logic_vector(7 downto 0); |
|
begin |
|
D := Data; |
C := CRC; |
|
NewCRC(0) := D(7) xor D(6) xor D(0) xor C(0) xor C(6) xor C(7); |
NewCRC(1) := D(6) xor D(1) xor D(0) xor C(0) xor C(1) xor C(6); |
NewCRC(2) := D(6) xor D(2) xor D(1) xor D(0) xor C(0) xor C(1) xor |
C(2) xor C(6); |
NewCRC(3) := D(7) xor D(3) xor D(2) xor D(1) xor C(1) xor C(2) xor |
C(3) xor C(7); |
NewCRC(4) := D(4) xor D(3) xor D(2) xor C(2) xor C(3) xor C(4); |
NewCRC(5) := D(5) xor D(4) xor D(3) xor C(3) xor C(4) xor C(5); |
NewCRC(6) := D(6) xor D(5) xor D(4) xor C(4) xor C(5) xor C(6); |
NewCRC(7) := D(7) xor D(6) xor D(5) xor C(5) xor C(6) xor C(7); |
|
return NewCRC; |
|
end nextCRC8_D8; |
|
end PCK_CRC8_D8; |
|
/shift_register.vhd
0,0 → 1,191
------------------------------------------------------------------------------- |
--* |
--* @short Shift-Register |
--* |
--* Control Register Description: |
--* @li Bit0: DGE : Global Device Enable |
--* @li Bit1: TX_EN: Transmit enable |
--* @li Bit2: RX_EN: Receive enable |
--* |
--* Generics described in top entity. |
--* @port opb_ctl_reg Control Register |
--* |
--* @see opb_spi_slave |
|
--* @version: 1.1 |
--* @date: 2007-11-11 |
--/ |
-- Version 1.0 Initial Release |
-- Version 1.1 rx_cnt/tx_cnt only increment if < C_SR_WIDTH |
-- Version 1.2 removed delays for simulation |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use IEEE.STD_LOGIC_ARITH.all; |
|
library work; |
use work.opb_spi_slave_pack.all; |
|
entity shift_register is |
|
generic ( |
C_SR_WIDTH : integer := 8; |
C_MSB_FIRST : boolean := true; |
C_CPOL : integer range 0 to 1 := 0; |
C_PHA : integer range 0 to 1 := 0); |
|
port ( |
rst : in std_logic; |
-- control register |
opb_ctl_reg : in std_logic_vector(C_OPB_CTL_REG_WIDTH-1 downto 0); |
-- external |
sclk : in std_logic; |
ss_n : in std_logic; |
mosi : in std_logic; |
miso_o : out std_logic; |
miso_i : in std_logic; |
miso_t : out std_logic; |
-- transmit fifo |
sr_tx_clk : out std_logic; |
sr_tx_en : out std_logic; |
sr_tx_data : in std_logic_vector(C_SR_WIDTH-1 downto 0); |
-- receive fifo |
sr_rx_clk : out std_logic; |
sr_rx_en : out std_logic; |
sr_rx_data : out std_logic_vector(C_SR_WIDTH-1 downto 0)); |
end shift_register; |
|
|
architecture behavior of shift_register is |
--* Global |
signal sclk_int : std_logic; |
signal sclk_int_inv : std_logic; |
signal rx_cnt : integer range 0 to 31 := 0; |
|
-- RX |
signal rx_sr_reg : std_logic_vector(C_SR_WIDTH-2 downto 0); |
signal sr_rx_en_int : std_logic; |
signal sr_rx_data_int : std_logic_vector(C_SR_WIDTH-1 downto 0); |
|
-- tx |
signal miso_int : std_logic; |
signal tx_cnt : integer range 0 to 31 := 0; |
signal sr_tx_en_int : std_logic; |
signal sr_tx_data_int : std_logic_vector(C_SR_WIDTH-1 downto 0); |
|
|
begin -- behavior |
|
miso_t <= ss_n; -- tristate |
|
|
sclk_int <= sclk when (C_PHA = 0 and C_CPOL = 0) else |
sclk when (C_PHA = 1 and C_CPOL = 1) else |
not sclk; |
|
|
sr_rx_en <= sr_rx_en_int; |
sr_tx_en <= sr_tx_en_int; |
|
--* reorder received bits if not "MSB_First" |
reorder_rx_bits : process(sr_rx_data_int) |
begin |
for i in 0 to C_SR_WIDTH-1 loop |
if C_MSB_FIRST then |
sr_rx_data(i) <= sr_rx_data_int(i); |
else |
sr_rx_data(C_SR_WIDTH-1-i) <= sr_rx_data_int(i); |
end if; |
end loop; -- i |
end process reorder_rx_bits; |
|
--* reorder transmit bits if not "MSB_First" |
reorder_tx_bits : process(sr_tx_data) |
begin |
for i in 0 to C_SR_WIDTH-1 loop |
if C_MSB_FIRST then |
sr_tx_data_int(i) <= sr_tx_data(i); |
else |
sr_tx_data_int(C_SR_WIDTH-1-i) <= sr_tx_data(i); |
end if; |
end loop; -- i |
end process reorder_tx_bits; |
|
|
----------------------------------------------------------------------------- |
|
sr_rx_clk <= sclk_int; |
|
sr_rx_data_int <= rx_sr_reg & mosi; |
|
--* RX-Shift-Register |
rx_shift_proc : process(rst, opb_ctl_reg, sclk_int) |
begin |
if (rst = '1' or opb_ctl_reg(C_OPB_CTL_REG_DGE) = '0' or opb_ctl_reg(C_OPB_CTL_REG_RX_EN) = '0') then |
rx_cnt <= 0; |
sr_rx_en_int <= '0'; |
rx_sr_reg <= (others => '0'); |
|
elsif rising_edge(sclk_int) then |
if (ss_n = '0') then |
rx_sr_reg <= rx_sr_reg(C_SR_WIDTH-3 downto 0) & mosi; |
if (rx_cnt = C_SR_WIDTH-2) then |
rx_cnt <= rx_cnt +1; |
sr_rx_en_int <= '1'; |
elsif (rx_cnt = C_SR_WIDTH-1) then |
rx_cnt <= 0; |
sr_rx_en_int <= '0'; |
else |
rx_cnt <= rx_cnt +1; |
end if; |
else |
-- ss_n high |
-- assert framing error if cnt != 0? |
sr_rx_en_int <= '0'; |
rx_cnt <= 0; |
end if; |
end if; |
end process rx_shift_proc; |
|
------------------------------------------------------------------------------- |
-- TX Shift Register |
sr_tx_clk <= sclk_int_inv; |
sclk_int_inv <= not sclk_int; |
|
miso_o <= sr_tx_data_int(C_SR_WIDTH-1) when (tx_cnt = 0) else |
miso_int; |
|
|
--* TX Shift-Register |
tx_shift_proc : process(rst, opb_ctl_reg, sclk_int_inv) |
begin |
if (rst = '1' or opb_ctl_reg(C_OPB_CTL_REG_DGE) = '0' or opb_ctl_reg(C_OPB_CTL_REG_TX_EN) = '0') then |
tx_cnt <= 0; |
sr_tx_en_int <= '0'; |
miso_int <= '0'; |
elsif rising_edge(sclk_int_inv) then |
if (ss_n = '0') then |
if (tx_cnt /= C_SR_WIDTH-1) then |
miso_int <= sr_tx_data_int(C_SR_WIDTH-1-(tx_cnt+1)); |
end if; |
if (tx_cnt = C_SR_WIDTH-2) then |
sr_tx_en_int <= '1'; |
tx_cnt <= tx_cnt +1; |
elsif (tx_cnt = C_SR_WIDTH-1) then |
tx_cnt <= 0; |
sr_tx_en_int <= '0'; |
else |
tx_cnt <= tx_cnt +1; |
end if; |
else |
-- ss_n high |
-- assert framing error if cnt != 0? |
sr_tx_en_int <= '0'; |
tx_cnt <= 0; |
end if; |
end if; |
end process tx_shift_proc; |
------------------------------------------------------------------------------- |
|
end behavior; |
/irq_ctl.vhd
0,0 → 1,65
------------------------------------------------------------------------------- |
--* |
--* @short Control Unit for IRQ detection, enable and clear |
--* |
--* @generic C_ACTIVE_EDGE Select active edge for IRQ-Source 0: H->L;1: L->H |
--* |
|
--* @version: 1.0 |
--* @date: 2007-11-11 |
--/ |
-- Version 1.1 |
-- Bugfix |
-- added syncronisation registers opb_fifo_flg_int_r[0,1] to prevent |
-- metastability |
------------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
|
entity irq_ctl is |
generic ( |
C_ACTIVE_EDGE : std_logic := '0'); |
port ( |
rst : in std_logic; |
clk : in std_logic; |
opb_fifo_flg : in std_logic; |
opb_ier : in std_logic; |
opb_isr : out std_logic; |
opb_isr_clr : in std_logic); |
|
end irq_ctl; |
|
architecture behavior of irq_ctl is |
|
signal opb_fifo_flg_int : std_logic; |
-- Sync to clock domain register |
signal opb_fifo_flg_int_r0 : std_logic; |
signal opb_fifo_flg_int_r1 : std_logic; |
|
|
signal opb_fifo_flg_reg : std_logic; |
begin -- behavior |
|
opb_fifo_flg_int_r0 <= opb_fifo_flg when (C_ACTIVE_EDGE = '1') else |
not opb_fifo_flg; |
|
irq_ctl_proc : process(rst, clk) |
begin |
if (rst = '1') then |
opb_isr <= '0'; |
elsif rising_edge(clk) then |
-- sync to clock domain |
opb_fifo_flg_int_r1 <= opb_fifo_flg_int_r0; |
opb_fifo_flg_int <= opb_fifo_flg_int_r1; |
|
opb_fifo_flg_reg <= opb_fifo_flg_int; |
if (opb_ier = '1' and opb_fifo_flg_int = '1' and opb_fifo_flg_reg = '0') then |
opb_isr <= '1'; |
elsif (opb_isr_clr = '1') then |
opb_isr <= '0'; |
end if; |
end if; |
end process irq_ctl_proc; |
|
|
end behavior; |
/ram.vhd
0,0 → 1,46
------------------------------------------------------------------------------- |
--* |
--* @short RAM Sync-Write, Async Read |
--* |
--* @generic C_FIFO_WIDTH RAM-With (1..xx) |
--* @generic C_FIFO_SIZE_WIDTH RAM Size = 2**C_FIFO_SIZE_WIDTH |
--* |
|
--* @version: 1.0 |
--* @date: 2007-11-11 |
--/ |
------------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
|
entity ram is |
generic ( |
C_FIFO_WIDTH : integer := 8; |
C_FIFO_SIZE_WIDTH : integer := 4); |
|
port (clk : in std_logic; |
we : in std_logic; |
a : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); |
dpra : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); |
di : in std_logic_vector(C_FIFO_WIDTH-1 downto 0); |
dpo : out std_logic_vector(C_FIFO_WIDTH-1 downto 0)); |
end ram; |
|
architecture behavior of ram is |
type ram_type is array (2**C_FIFO_SIZE_WIDTH-1 downto 0) of std_logic_vector (C_FIFO_WIDTH-1 downto 0); |
signal RAM : ram_type; |
begin |
|
process (clk) |
begin |
if (clk'event and clk = '1') then |
if (we = '1') then |
RAM(conv_integer(a)) <= di; |
end if; |
end if; |
end process; |
|
dpo <= RAM(conv_integer(dpra)); |
|
end behavior; |
/gray_adder.vhd
0,0 → 1,68
------------------------------------------------------------------------------- |
--* |
--* @short gray Adder |
--* |
--* @generic width with of adder vector |
--* |
|
--* @version: 1.0 |
--* @date: 2007-11-11 |
--/ |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
use ieee.std_logic_arith.all; |
|
entity gray_adder is |
generic ( |
width : integer := 4); |
port ( |
in_gray : in std_logic_vector(width-1 downto 0); |
out_gray : out std_logic_vector(width-1 downto 0)); |
end gray_adder; |
|
architecture behavior of gray_adder is |
--* convert gray to bin |
component gray2bin |
generic ( |
width : integer); |
port ( |
in_gray : in std_logic_vector(width-1 downto 0); |
out_bin : out std_logic_vector(width-1 downto 0)); |
end component; |
--* convert bin to gray |
component bin2gray |
generic ( |
width : integer); |
port ( |
in_bin : in std_logic_vector(width-1 downto 0); |
out_gray : out std_logic_vector(width-1 downto 0)); |
end component; |
|
signal out_bin : std_logic_vector(width-1 downto 0); |
signal bin_add : std_logic_vector(width-1 downto 0); |
|
begin -- behavior |
--* convert input gray signal to binary |
gray2bin_1 : gray2bin |
generic map ( |
width => width) |
port map ( |
in_gray => in_gray, |
out_bin => out_bin); |
|
--* add one to signal |
bin_add <= out_bin + 1; |
--* convert signal back to gray |
bin2gray_1 : bin2gray |
generic map ( |
width => width) |
port map ( |
in_bin => bin_add, |
out_gray => out_gray); |
|
|
|
end behavior; |
/fifo.vhd
0,0 → 1,262
------------------------------------------------------------------------------- |
--* |
--* @short Configurable FIFO |
--* |
--* @generic C_FIFO_WIDTH RAM-With (1..xx) |
--* @generic C_FIFO_SIZE_WIDTH RAM Size = 2**C_FIFO_SIZE_WIDTH |
--* @generic C_SYNC_TO Sync FIFO Flags to read or write clock |
--* |
|
--* @version: 1.0 |
--* @date: 2007-11-11 |
--/ |
------------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
use ieee.std_logic_arith.all; |
|
|
entity fifo is |
generic ( |
C_FIFO_WIDTH : integer := 8; |
C_FIFO_SIZE_WIDTH : integer := 4; |
C_SYNC_TO : string := "RD"); |
port ( |
rst : in std_logic; |
-- write port |
wr_clk : in std_logic; |
wr_en : in std_logic; |
din : in std_logic_vector(C_FIFO_WIDTH-1 downto 0); |
-- read port |
rd_clk : in std_logic; |
rd_en : in std_logic; |
dout : out std_logic_vector(C_FIFO_WIDTH-1 downto 0); |
-- flags |
empty : out std_logic; |
full : out std_logic; |
overflow : out std_logic; |
underflow : out std_logic; |
prog_empty_thresh : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); |
prog_full_thresh : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); |
prog_empty : out std_logic; |
prog_full : out std_logic); |
|
end fifo; |
|
architecture behavior of fifo is |
--* ram with sync write and async read |
component ram |
generic ( |
C_FIFO_WIDTH : integer := 8; |
C_FIFO_SIZE_WIDTH : integer := 4); |
port ( |
clk : in std_logic; |
we : in std_logic; |
a : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); |
dpra : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); |
di : in std_logic_vector(C_FIFO_WIDTH-1 downto 0); |
dpo : out std_logic_vector(C_FIFO_WIDTH-1 downto 0)); |
end component; |
|
--* component generates fifo flag |
component fifo_prog_flags |
generic ( |
C_FIFO_SIZE_WIDTH : integer; |
C_SYNC_TO : string); |
port ( |
rst : in std_logic; |
clk : in std_logic; |
cnt_grey : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); |
cnt : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); |
prog_full_thresh : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); |
prog_empty_thresh : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); |
prog_empty : out std_logic; |
prog_full : out std_logic); |
end component; |
|
--* logic coded gray counter |
component gray_adder |
generic ( |
width : integer); |
port ( |
in_gray : in std_logic_vector(width-1 downto 0); |
out_gray : out std_logic_vector(width-1 downto 0)); |
end component; |
|
signal wr_cnt_gray_add_one : std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); |
signal wr_cnt_next_grey_add_one : std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); |
signal rd_cnt_grey_add_one : std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); |
|
attribute fsm_extract : string; |
-- wr_clock domain |
-- main wr grey code counter |
signal wr_cnt_grey : std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); |
attribute fsm_extract of wr_cnt_grey : signal is "no"; |
|
-- main grey code counter for full |
signal wr_cnt_next_grey : std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); |
attribute fsm_extract of wr_cnt_next_grey : signal is "no"; |
|
-- rd_clk domain |
-- main rd grey code counter |
signal rd_cnt_grey : std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); |
attribute fsm_extract of rd_cnt_grey : signal is "no"; |
|
-- binary counter for prog full/empty |
signal rd_cnt : std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); |
signal wr_cnt : std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); |
|
signal empty_int : std_logic; |
signal full_int : std_logic; |
|
begin -- behavior |
|
empty <= empty_int; |
full <= full_int; |
|
--* write counter generation |
fifo_write_proc: process(rst, wr_clk) |
begin |
if (rst = '1') then |
wr_cnt_grey <= (others => '0'); |
wr_cnt <= (others => '0'); |
wr_cnt_next_grey(C_FIFO_SIZE_WIDTH-1 downto 1) <= (others => '0'); |
wr_cnt_next_grey(0) <= '1'; |
elsif rising_edge(wr_clk) then |
if (wr_en = '1') then |
wr_cnt <= wr_cnt+1; |
|
-- wr_cnt_grey <= add_grey_rom(conv_integer(wr_cnt_grey)); |
wr_cnt_grey <= wr_cnt_gray_add_one; |
|
-- wr_cnt_next_grey <= add_grey_rom(conv_integer(wr_cnt_next_grey)); |
wr_cnt_next_grey <= wr_cnt_next_grey_add_one; |
|
end if; |
end if; |
end process fifo_write_proc; |
|
--* add one to wr_cnt_gray |
gray_adder_1 : gray_adder |
generic map ( |
width => C_FIFO_SIZE_WIDTH) |
port map ( |
in_gray => wr_cnt_grey, |
out_gray => wr_cnt_gray_add_one); |
|
--* add one to wr_cnt_next_grey |
gray_adder_2 : gray_adder |
generic map ( |
width => C_FIFO_SIZE_WIDTH) |
port map ( |
in_gray => wr_cnt_next_grey, |
out_gray => wr_cnt_next_grey_add_one); |
|
|
--* read counter generation |
fifo_read_proc: process(rst, rd_clk) |
begin |
if (rst = '1') then |
rd_cnt_grey <= (others => '0'); |
rd_cnt <= (others => '0'); |
elsif rising_edge(rd_clk) then |
-- rd grey code counter |
if (rd_en = '1') then |
-- rd_cnt_grey <= add_grey_rom(conv_integer(rd_cnt_grey)); |
rd_cnt_grey <= rd_cnt_grey_add_one; |
rd_cnt <= rd_cnt+1; |
end if; |
end if; |
end process fifo_read_proc; |
|
--* add one to rd_cnt_grey |
gray_adder_3 : gray_adder |
generic map ( |
width => C_FIFO_SIZE_WIDTH) |
port map ( |
in_gray => rd_cnt_grey, |
out_gray => rd_cnt_grey_add_one); |
|
|
--* FIFO Memory |
ram_1 : ram |
generic map ( |
C_FIFO_WIDTH => C_FIFO_WIDTH, |
C_FIFO_SIZE_WIDTH => C_FIFO_SIZE_WIDTH) |
port map ( |
clk => wr_clk, |
we => wr_en, |
a => wr_cnt_grey, |
di => din, |
dpra => rd_cnt_grey, |
dpo => dout); |
|
|
--* generate overflow |
gen_of_proc: process(rst, wr_clk) |
begin |
if (rst = '1') then |
overflow <= '0'; |
elsif rising_edge(wr_clk) then |
if (full_int = '1' and wr_en = '1') then |
overflow <= '1'; |
end if; |
end if; |
end process gen_of_proc; |
|
--* generate underflow |
gen_uf_proc: process(rst, rd_clk) |
begin |
if (rst = '1') then |
underflow <= '0'; |
elsif rising_edge(rd_clk) then |
if (empty_int = '1' and rd_en = '1') then |
underflow <= '1'; |
end if; |
end if; |
end process gen_uf_proc; |
|
-- generate empty |
empty_int <= '1' when (wr_cnt_grey = rd_cnt_grey) else |
'0'; |
|
-- generate full |
full_int <= '1' when (wr_cnt_next_grey = rd_cnt_grey) else |
'0'; |
|
--* select clock side for flags |
u1 : if (C_SYNC_TO = "WR") generate |
--* sync flags to write clock |
fifo_prog_flags_1 : fifo_prog_flags |
generic map ( |
C_FIFO_SIZE_WIDTH => C_FIFO_SIZE_WIDTH, |
C_SYNC_TO => C_SYNC_TO) |
port map ( |
rst => rst, |
clk => wr_clk, |
cnt_grey => rd_cnt_grey, |
cnt => wr_cnt, |
prog_full_thresh => prog_full_thresh, |
prog_empty_thresh => prog_empty_thresh, |
prog_empty => prog_empty, |
prog_full => prog_full); |
end generate u1; |
|
u2 : if (C_SYNC_TO = "RD") generate |
--* sync flags to read clock |
fifo_prog_flags_1 : fifo_prog_flags |
generic map ( |
C_FIFO_SIZE_WIDTH => C_FIFO_SIZE_WIDTH, |
C_SYNC_TO => C_SYNC_TO) |
port map ( |
rst => rst, |
clk => rd_clk, |
cnt_grey => wr_cnt_grey, |
cnt => rd_cnt, |
prog_full_thresh => prog_full_thresh, |
prog_empty_thresh => prog_empty_thresh, |
prog_empty => prog_empty, |
prog_full => prog_full); |
end generate u2; |
end behavior; |
/fifo_prog_flags.vhd
0,0 → 1,96
------------------------------------------------------------------------------- |
--* |
--* @short Generate fifo flags |
--* |
--* @generic C_FIFO_SIZE_WIDTH RAM Size = 2**C_FIFO_SIZE_WIDTH |
--* @generic C_SYNC_TO Sync FIFO Flags to read or write clock |
--* |
|
--* @version: 1.0 |
--* @date: 2007-11-11 |
--/ |
------------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
use ieee.std_logic_arith.all; |
|
|
entity fifo_prog_flags is |
generic ( |
C_FIFO_SIZE_WIDTH : integer := 4; |
C_SYNC_TO : string := "WR"); |
port ( |
rst : in std_logic; |
clk : in std_logic; |
cnt_grey : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); |
cnt : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); |
prog_full_thresh : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); |
prog_empty_thresh : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); |
prog_empty : out std_logic; |
prog_full : out std_logic); |
|
end fifo_prog_flags; |
architecture behavior of fifo_prog_flags is |
|
-- sync register for clock domain transfer |
signal cnt_grey_reg : std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); |
|
type rom_t is array (0 to (2**C_FIFO_SIZE_WIDTH)-1) of std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); |
|
--* convert from gray to binary |
component gray2bin |
generic ( |
width : integer); |
port ( |
in_gray : in std_logic_vector(width-1 downto 0); |
out_bin : out std_logic_vector(width-1 downto 0)); |
end component; |
|
signal cnt_bin_reg : std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); |
|
begin -- behavior |
|
--* Generate fifo flags |
gen_flags_proc: process(rst, clk) |
variable diff : std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); |
begin |
if (rst = '1') then |
cnt_grey_reg <= (others => '0'); |
prog_empty <= '1'; |
prog_full <= '0'; |
elsif rising_edge(clk) then |
-- transfer to rd_clk domain |
cnt_grey_reg <= cnt_grey; |
-- fifo prog full/empty |
if (C_SYNC_TO = "RD") then |
-- diff := conv_grey_rom(conv_integer(cnt_grey_reg))- cnt; |
diff := cnt_bin_reg - cnt; |
else |
-- diff := cnt - conv_grey_rom(conv_integer(cnt_grey_reg)); |
diff := cnt - cnt_bin_reg; |
end if; |
|
if (diff > prog_full_thresh) then |
prog_full <= '1'; |
else |
prog_full <= '0'; |
end if; |
|
if (diff < prog_empty_thresh) then |
prog_empty <= '1'; |
else |
prog_empty <= '0'; |
end if; |
end if; |
end process gen_flags_proc; |
|
--* convert gray to bin |
gray2bin_1: gray2bin |
generic map ( |
width => C_FIFO_SIZE_WIDTH) |
port map ( |
in_gray => cnt_grey_reg, |
out_bin => cnt_bin_reg); |
|
end behavior; |
/bin2gray.vhd
0,0 → 1,45
------------------------------------------------------------------------------- |
--* |
--* @short convert binary input vector to gray |
--* |
--* @generic width with of input vector |
--* |
|
--* @version: 1.0 |
--* @date: 2007-11-11 |
--/ |
------------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
use ieee.std_logic_arith.all; |
|
entity bin2gray is |
generic ( |
width : integer := 4); |
port ( |
in_bin : in std_logic_vector(width-1 downto 0); |
out_gray : out std_logic_vector(width-1 downto 0)); |
end bin2gray; |
|
architecture behavior of bin2gray is |
|
begin -- behavior |
|
-- Sequence: 0,1,3,2,6,7,5,4,C,D,F,E,A,B,9,8 |
--* convert binary input vector to gray |
bin2gray_proc : process(in_bin) |
begin |
out_gray(width-1) <= in_bin(width-1); |
-- out_gray(3) <= in_bin(3); |
|
for i in 1 to width-1 loop |
out_gray(width-1-i) <= in_bin(width-i) xor in_bin(width-1-i); |
end loop; -- i |
end process bin2gray_proc; |
|
-- i=1 out_gray(2) <= in_bin(3) xor in_bin(2); |
-- i=2 out_gray(1) <= in_bin(2) xor in_bin(1); |
-- i=3 out_gray(0) <= in_bin(1) xor in_bin(0); |
|
end behavior; |
/gray2bin.vhd
0,0 → 1,45
------------------------------------------------------------------------------- |
--* |
--* @short convert gray input vector to binary |
--* |
--* @generic width with of input vector |
--* |
|
--* @version: 1.0 |
--* @date: 2007-11-11 |
--/ |
------------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
use ieee.std_logic_arith.all; |
|
entity gray2bin is |
generic ( |
width : integer := 4); |
port ( |
in_gray : in std_logic_vector(width-1 downto 0); |
out_bin : out std_logic_vector(width-1 downto 0)); |
end gray2bin; |
|
architecture behavior of gray2bin is |
|
signal out_bin_int : std_logic_vector(width-1 downto 0); |
begin -- behavior |
|
out_bin <= out_bin_int; |
|
-- Sequence: 0,1,3,2,6,7,5,4,C,D,F,E,A,B,9,8 |
--* convert gray input vector to binary |
gray2bin_proc: process(in_gray, out_bin_int) |
begin |
out_bin_int(width-1) <= in_gray(width-1); |
-- out_gray(3) <= in_gray(3); |
for i in 1 to width-1 loop |
out_bin_int(width-1-i) <= out_bin_int(width-i) xor in_gray(width-1-i); |
end loop ; -- i |
end process gray2bin_proc; |
-- i=1 out_bin(2) <= out_bin_int(3) xor out_bin(2); |
-- i=2 out_bin(1) <= out_bin_int(2) xor out_bin(1); |
-- i=3 out_bin(0) <= out_bin_int(1) xor out_bin(0); |
end behavior; |