From 91cac434b4bc40ca4250dc98b4317cc97762d8be Mon Sep 17 00:00:00 2001 From: Michael Boehmer Date: Sun, 5 Jun 2022 15:22:41 +0200 Subject: [PATCH] bug with write_mem... --- media_interfaces/med_ecp5_sfp_sync_RS.vhd | 2 +- special/spi_databus_memory.vhd | 166 +-- special/spi_flash_and_fpga_reload_record.vhd | 26 +- special/spi_master.vhd | 172 ++- special/spi_slim.vhd | 1021 +++++++++-------- ...t16_endpoint_hades_full_handler_record.vhd | 12 +- 6 files changed, 700 insertions(+), 699 deletions(-) diff --git a/media_interfaces/med_ecp5_sfp_sync_RS.vhd b/media_interfaces/med_ecp5_sfp_sync_RS.vhd index ea21734..8054c23 100644 --- a/media_interfaces/med_ecp5_sfp_sync_RS.vhd +++ b/media_interfaces/med_ecp5_sfp_sync_RS.vhd @@ -344,7 +344,7 @@ gen_SERDES: if LINK_SPEED = 200 generate serdes_sync_0_200M_rxdata => rx_data, serdes_sync_0_200M_rx_k => rx_k, serdes_sync_0_200M_rx_disp_err => open, - serdes_sync_0_200M_rx_cv_err => rx_error(0), + serdes_sync_0_200M_rx_cv_err => rx_error, serdes_sync_0_200M_signal_detect_c => '1', -- LSM enable serdes_sync_0_200M_rx_cdr_lol_s => rx_cdr_lol, serdes_sync_0_200M_rx_los_low_s => rx_los_low, diff --git a/special/spi_databus_memory.vhd b/special/spi_databus_memory.vhd index 1caaae7..d392bfd 100644 --- a/special/spi_databus_memory.vhd +++ b/special/spi_databus_memory.vhd @@ -33,7 +33,8 @@ architecture Behavioral of spi_databus_memory is attribute HGROUP : string; -- for whole architecture attribute HGROUP of Behavioral : architecture is "SPI_group"; --- Signals + + -- Signals type STATES is (SLEEP,RD_RDY,WR_RDY,RD_ACK,WR_ACK,DONE); signal CURRENT_STATE, NEXT_STATE: STATES; @@ -56,100 +57,99 @@ stat(63 downto 0) <= (others => '0'); --------------------------------------------------------- -- Statemachine -- --------------------------------------------------------- - STATE_MEM: process( clk_in) - begin - if( rising_edge(clk_in) ) then - if( reset_in = '1' ) then - CURRENT_STATE <= SLEEP; - BUS_ack <= '0'; - store_wr <= '0'; - store_rd <= '0'; - else - CURRENT_STATE <= NEXT_STATE; - BUS_ack <= BUS_ack_x; - store_wr <= store_wr_x; - store_rd <= store_rd_x; - end if; - end if; - end process STATE_MEM; +STATE_MEM: process( CLK_IN ) +begin + if( rising_edge(CLK_IN) ) then + if( RESET_IN = '1' ) then + CURRENT_STATE <= SLEEP; + bus_ack <= '0'; + store_wr <= '0'; + store_rd <= '0'; + else + CURRENT_STATE <= NEXT_STATE; + bus_ack <= bus_ack_x; + store_wr <= store_wr_x; + store_rd <= store_rd_x; + end if; + end if; +end process STATE_MEM; -- Transition matrix - TRANSFORM: process(CURRENT_STATE, BUS_read_in, BUS_write_in ) - begin +TRANSFORM: process(CURRENT_STATE, BUS_READ_IN, BUS_WRITE_IN ) +begin + NEXT_STATE <= SLEEP; + bus_ack_x <= '0'; + store_wr_x <= '0'; + store_rd_x <= '0'; + case CURRENT_STATE is + when SLEEP => + if ( (BUS_READ_IN = '1') ) then + NEXT_STATE <= RD_RDY; + store_rd_x <= '1'; + elsif( (BUS_WRITE_IN = '1') ) then + NEXT_STATE <= WR_RDY; + store_wr_x <= '1'; + else + NEXT_STATE <= SLEEP; + end if; + + when RD_RDY => + NEXT_STATE <= RD_ACK; + + when WR_RDY => + NEXT_STATE <= WR_ACK; + + when RD_ACK => + if( BUS_READ_IN = '0' ) then + NEXT_STATE <= DONE; + bus_ack_x <= '1'; + else + NEXT_STATE <= RD_ACK; + bus_ack_x <= '1'; + end if; + + when WR_ACK => + if( BUS_WRITE_IN = '0' ) then + NEXT_STATE <= DONE; + bus_ack_x <= '1'; + else + NEXT_STATE <= WR_ACK; + bus_ack_x <= '1'; + end if; + + when DONE => + NEXT_STATE <= SLEEP; + + when others => NEXT_STATE <= SLEEP; - BUS_ack_x <= '0'; - store_wr_x <= '0'; - store_rd_x <= '0'; - case CURRENT_STATE is - when SLEEP => - if ( (BUS_read_in = '1') ) then - NEXT_STATE <= RD_RDY; - store_rd_x <= '1'; - elsif( (BUS_write_in = '1') ) then - NEXT_STATE <= WR_RDY; - store_wr_x <= '1'; - else - NEXT_STATE <= SLEEP; - end if; - - when RD_RDY => - NEXT_STATE <= RD_ACK; - - when WR_RDY => - NEXT_STATE <= WR_ACK; - - when RD_ACK => - if( BUS_read_in = '0' ) then - NEXT_STATE <= DONE; - BUS_ack_x <= '1'; - else - NEXT_STATE <= RD_ACK; - BUS_ack_x <= '1'; - end if; - - when WR_ACK => - if( BUS_write_in = '0' ) then - NEXT_STATE <= DONE; - BUS_ack_x <= '1'; - else - NEXT_STATE <= WR_ACK; - BUS_ack_x <= '1'; - end if; - - when DONE => - NEXT_STATE <= SLEEP; - - when others => - NEXT_STATE <= SLEEP; end case; end process TRANSFORM; - --------------------------------------------------------- -- data handling -- --------------------------------------------------------- THE_BUS_SPI_DPRAM: spi_dpram_32_to_8 - port map( - DATAINA => BUS_data_in, - ADDRESSA => BUS_addr_in, - CLOCKA => clk_in, - CLOCKENA => '1', - WRA => store_wr, - RESETA => reset_in, - QA => buf_BUS_data_out, - -- B side is state machine - DATAINB => bram_rd_d_in, - ADDRESSB => bram_addr_in, - CLOCKB => clk_in, - CLOCKENB => '1', - WRB => bram_we_in, - RESETB => reset_in, - QB => bram_wr_d_out - ); +port map( + DATAINA => BUS_DATA_IN, + ADDRESSA => BUS_ADDR_IN, + CLOCKA => CLK_IN, + CLOCKENA => '1', + WRA => store_wr, + RESETA => RESET_IN, + QA => buf_bus_data_out, + -- B side is state machine + DATAINB => BRAM_RD_D_IN, + ADDRESSB => BRAM_ADDR_IN, + CLOCKB => CLK_IN, + CLOCKENB => '1', + WRB => BRAM_WE_IN, + RESETB => RESET_IN, + QB => BRAM_WR_D_OUT +); -- output signals -BUS_data_out <= buf_BUS_data_out; -BUS_ack_out <= BUS_ack; +BUS_DATA_OUT <= buf_bus_data_out; +BUS_ACK_OUT <= bus_ack; end Behavioral; diff --git a/special/spi_flash_and_fpga_reload_record.vhd b/special/spi_flash_and_fpga_reload_record.vhd index aaa37c8..96c1250 100644 --- a/special/spi_flash_and_fpga_reload_record.vhd +++ b/special/spi_flash_and_fpga_reload_record.vhd @@ -22,7 +22,8 @@ entity spi_flash_and_fpga_reload_record is SPI_CS_OUT : out std_logic; SPI_SCK_OUT : out std_logic; SPI_SDO_OUT : out std_logic; - SPI_SDI_IN : in std_logic + SPI_SDI_IN : in std_logic; + DEBUG_OUT : out std_logic_vector(31 downto 0) ); end entity; @@ -48,8 +49,11 @@ architecture flash_reboot_arch of spi_flash_and_fpga_reload_record is signal spi_bram_rd_d : std_logic_vector(7 downto 0); signal spi_bram_we : std_logic; - signal dat_write_ack, dat_dataready : std_logic; - + signal dat_write_ack : std_logic; + signal dat_dataready : std_logic; + + signal spi_debug : std_logic_vector(31 downto 0); + begin BUS_TX.ack <= dat_dataready or dat_write_ack; @@ -128,9 +132,21 @@ THE_SPI_MASTER: spi_master BRAM_RD_D_OUT => spi_bram_rd_d, BRAM_WE_OUT => spi_bram_we, -- Status lines - STAT => open + STAT => spi_debug --open ); + DEBUG_OUT(0) <= spictrl_read_en; + DEBUG_OUT(1) <= spictrl_write_en; + DEBUG_OUT(2) <= spictrl_ack; + DEBUG_OUT(3) <= spictrl_busy; + DEBUG_OUT(4) <= spimem_read_en; + DEBUG_OUT(5) <= spimem_write_en; + DEBUG_OUT(6) <= spimem_ack; + DEBUG_OUT(7) <= spi_debug(0); -- spi_start + DEBUG_OUT(8) <= spi_debug(1); -- spi_busy + + DEBUG_OUT(31 downto 9) <= (others => '0'); + -- data memory for SPI accesses THE_SPI_MEMORY: spi_databus_memory port map( @@ -151,7 +167,7 @@ THE_SPI_MEMORY: spi_databus_memory -- Status lines STAT => open ); - + --------------------------------------------------------------------------- -- Reboot FPGA --------------------------------------------------------------------------- diff --git a/special/spi_master.vhd b/special/spi_master.vhd index 4caf5f1..31d6f82 100644 --- a/special/spi_master.vhd +++ b/special/spi_master.vhd @@ -41,34 +41,34 @@ architecture Behavioral of spi_master is attribute HGROUP of Behavioral : architecture is "SPI_group"; -- Signals - type STATES is (SLEEP,DONE);--RD_BSY,WR_BSY,RD_RDY,WR_RDY,RD_ACK,WR_ACK - signal CURRENT_STATE, NEXT_STATE: STATES; + type STATES is (SLEEP,DONE);--RD_BSY,WR_BSY,RD_RDY,WR_RDY,RD_ACK,WR_ACK + signal CURRENT_STATE, NEXT_STATE: STATES; - signal status_data : std_logic_vector(31 downto 0); - signal spi_busy : std_logic; + signal status_data : std_logic_vector(31 downto 0); + signal spi_busy : std_logic; - signal reg_ctrl_data : std_logic_vector(31 downto 0); -- CMD, ADH, ADM, ADL - signal reg_status_data : std_logic_vector(31 downto 0); -- MAX + signal reg_ctrl_data : std_logic_vector(31 downto 0); -- CMD, ADH, ADM, ADL + signal reg_status_data : std_logic_vector(31 downto 0); -- MAX - signal reg_bus_data_out : std_logic_vector(31 downto 0); -- readback + signal reg_bus_data_out : std_logic_vector(31 downto 0); -- readback - signal spi_bsm : std_logic_vector(7 downto 0); - signal spi_debug : std_logic_vector(31 downto 0); + signal spi_bsm : std_logic_vector(7 downto 0); + signal spi_debug : std_logic_vector(31 downto 0); - signal spi_start_x : std_logic; - signal spi_start : std_logic; + signal spi_start_x : std_logic; + signal spi_start : std_logic; - -- State machine signals - signal bus_busy_x : std_logic; - signal bus_busy : std_logic; - signal bus_ack_x : std_logic; - signal bus_ack : std_logic; - signal store_wr_x : std_logic; - signal store_wr : std_logic; - signal store_rd_x : std_logic; - signal store_rd : std_logic; + -- State machine signals + signal bus_busy_x : std_logic; + signal bus_busy : std_logic; + signal bus_ack_x : std_logic; + signal bus_ack : std_logic; + signal store_wr_x : std_logic; + signal store_wr : std_logic; + signal store_rd_x : std_logic; + signal store_rd : std_logic; - signal reset_i : std_logic; + signal reset_i : std_logic; attribute syn_preserve : boolean; attribute syn_keep : boolean; @@ -146,67 +146,33 @@ begin store_wr_x <= '0'; store_rd_x <= '0'; case CURRENT_STATE is - when SLEEP => - if ( (spi_busy = '0') and (bus_read_in = '1') ) then - NEXT_STATE <= DONE; - store_rd_x <= '1'; - elsif( (spi_busy = '0') and (bus_write_in = '1') ) then - NEXT_STATE <= DONE; - store_wr_x <= '1'; - elsif( (bus_addr_in(0) = '0') and (spi_busy = '1') and (bus_read_in = '1') ) then - NEXT_STATE <= SLEEP; -- CMD register is busy protected - bus_busy_x <= '1'; - elsif( (bus_addr_in(0) = '0') and (spi_busy = '1') and (bus_write_in = '1') ) then - NEXT_STATE <= SLEEP; -- CMD register is busy protected - bus_busy_x <= '1'; - elsif( (bus_addr_in(0) = '1') and (spi_busy = '1') and (bus_read_in = '1') ) then - NEXT_STATE <= DONE; -- STATUS register is not - store_rd_x <= '1'; - elsif( (bus_addr_in(0) = '1') and (spi_busy = '1') and (bus_write_in = '1') ) then - NEXT_STATE <= DONE; -- STATUS register is not - store_wr_x <= '1'; - else - NEXT_STATE <= SLEEP; - end if; --- when RD_RDY => --- NEXT_STATE <= RD_ACK; --- bus_ack_x <= '1'; --- when WR_RDY => --- NEXT_STATE <= WR_ACK; --- bus_ack_x <= '1'; --- when RD_ACK => --- if( bus_read_in = '0' ) then --- NEXT_STATE <= DONE; --- else --- NEXT_STATE <= RD_ACK; --- bus_ack_x <= '1'; --- end if; --- when WR_ACK => --- if( bus_write_in = '0' ) then --- NEXT_STATE <= DONE; --- else --- NEXT_STATE <= WR_ACK; --- bus_ack_x <= '1'; --- end if; --- when RD_BSY => --- if( bus_read_in = '0' ) then --- NEXT_STATE <= DONE; --- else --- NEXT_STATE <= RD_BSY; --- bus_busy_x <= '1'; --- end if; --- when WR_BSY => --- if( bus_write_in = '0' ) then --- NEXT_STATE <= DONE; --- else --- NEXT_STATE <= WR_BSY; --- bus_busy_x <= '1'; --- end if; - when DONE => - NEXT_STATE <= SLEEP; - bus_ack_x <= '1'; - when others => - NEXT_STATE <= SLEEP; + when SLEEP => + if ( (spi_busy = '0') and (bus_read_in = '1') ) then + NEXT_STATE <= DONE; + store_rd_x <= '1'; + elsif( (spi_busy = '0') and (bus_write_in = '1') ) then + NEXT_STATE <= DONE; + store_wr_x <= '1'; + elsif( (bus_addr_in(0) = '0') and (spi_busy = '1') and (bus_read_in = '1') ) then + NEXT_STATE <= SLEEP; -- CMD register is busy protected + bus_busy_x <= '1'; + elsif( (bus_addr_in(0) = '0') and (spi_busy = '1') and (bus_write_in = '1') ) then + NEXT_STATE <= SLEEP; -- CMD register is busy protected + bus_busy_x <= '1'; + elsif( (bus_addr_in(0) = '1') and (spi_busy = '1') and (bus_read_in = '1') ) then + NEXT_STATE <= DONE; -- STATUS register is not + store_rd_x <= '1'; + elsif( (bus_addr_in(0) = '1') and (spi_busy = '1') and (bus_write_in = '1') ) then + NEXT_STATE <= DONE; -- STATUS register is not + store_wr_x <= '1'; + else + NEXT_STATE <= SLEEP; + end if; + when DONE => + NEXT_STATE <= SLEEP; + bus_ack_x <= '1'; + when others => + NEXT_STATE <= SLEEP; end case; end process TRANSFORM; @@ -216,23 +182,23 @@ end process TRANSFORM; -- register write THE_WRITE_REG_PROC: process( clk_in ) - begin - if( rising_edge(clk_in) ) then - if ( reset_i = '1' ) then - reg_ctrl_data <= (others => '0'); - reg_status_data <= (others => '0'); - spi_start <= '0'; - elsif( (store_wr = '1') and (bus_addr_in(0) = '0') ) then - reg_ctrl_data <= bus_data_in; - spi_start <= spi_start_x; - elsif( (store_wr = '1') and (bus_addr_in(0) = '1') ) then - reg_status_data <= bus_data_in; - spi_start <= spi_start_x; - else - spi_start <= spi_start_x; - end if; - end if; - end process THE_WRITE_REG_PROC; +begin + if( rising_edge(clk_in) ) then + if ( reset_i = '1' ) then + reg_ctrl_data <= (others => '0'); + reg_status_data <= (others => '0'); + spi_start <= '0'; + elsif( (store_wr = '1') and (bus_addr_in(0) = '0') ) then + reg_ctrl_data <= bus_data_in; + spi_start <= spi_start_x; + elsif( (store_wr = '1') and (bus_addr_in(0) = '1') ) then + reg_status_data <= bus_data_in; + spi_start <= spi_start_x; + else + spi_start <= spi_start_x; + end if; + end if; +end process THE_WRITE_REG_PROC; spi_start_x <= '1' when ( (store_wr = '1') and (bus_addr_in(0) = '0') ) else '0'; @@ -262,9 +228,9 @@ status_data(22 downto 0) <= (others => '0'); bus_ack_out <= bus_ack; bus_busy_out <= bus_busy; bus_data_out <= reg_bus_data_out; -stat(31 downto 3) <= spi_debug(31 downto 3); --status_data; -stat(2) <= spi_start; -stat(1) <= bus_write_in; -stat(0) <= bus_read_in; + +stat(31 downto 2) <= spi_debug(31 downto 2); +stat(1) <= spi_busy; +stat(0) <= spi_start; end Behavioral; diff --git a/special/spi_slim.vhd b/special/spi_slim.vhd index 0d7d150..0734c29 100644 --- a/special/spi_slim.vhd +++ b/special/spi_slim.vhd @@ -10,136 +10,135 @@ use work.trb_net_components.all; -- missing: end of PP/RDCMD by data_done signal. entity spi_slim is - generic( - SLOW_SPI : integer range c_NO to c_YES := c_YES - ); - port( - SYSCLK : in std_logic; -- 100MHz sysclock - RESET : in std_logic; -- synchronous reset - -- Command interface - START_IN : in std_logic; -- one start pulse - BUSY_OUT : out std_logic; -- SPI transactions are ongoing - CMD_IN : in std_logic_vector(7 downto 0); -- SPI command byte - ADL_IN : in std_logic_vector(7 downto 0); -- low address byte - ADM_IN : in std_logic_vector(7 downto 0); -- mid address byte - ADH_IN : in std_logic_vector(7 downto 0); -- high address byte - MAX_IN : in std_logic_vector(7 downto 0); -- number of bytes to write / read (PP/RDCMD) - TXDATA_IN : in std_logic_vector(7 downto 0); -- byte to be transmitted next - TX_RD_OUT : out std_logic; - RXDATA_OUT : out std_logic_vector(7 downto 0); -- current received byte - RX_WR_OUT : out std_logic; - TX_RX_A_OUT : out std_logic_vector(7 downto 0); -- memory block counter for PP/RDCMD - -- SPI interface - SPI_SCK_OUT : out std_logic; - SPI_CS_OUT : out std_logic; - SPI_SDI_IN : in std_logic; - SPI_SDO_OUT : out std_logic; - -- DEBUG - CLK_EN_OUT : out std_logic; - BSM_OUT : out std_logic_vector(7 downto 0); - DEBUG_OUT : out std_logic_vector(31 downto 0) - ); + generic( + SLOW_SPI : integer range c_NO to c_YES := c_YES + ); + port( + SYSCLK : in std_logic; -- 100MHz sysclock + RESET : in std_logic; -- synchronous reset + -- Command interface + START_IN : in std_logic; -- one start pulse + BUSY_OUT : out std_logic; -- SPI transactions are ongoing + CMD_IN : in std_logic_vector(7 downto 0); -- SPI command byte + ADL_IN : in std_logic_vector(7 downto 0); -- low address byte + ADM_IN : in std_logic_vector(7 downto 0); -- mid address byte + ADH_IN : in std_logic_vector(7 downto 0); -- high address byte + MAX_IN : in std_logic_vector(7 downto 0); -- number of bytes to write / read (PP/RDCMD) + TXDATA_IN : in std_logic_vector(7 downto 0); -- byte to be transmitted next + TX_RD_OUT : out std_logic; + RXDATA_OUT : out std_logic_vector(7 downto 0); -- current received byte + RX_WR_OUT : out std_logic; + TX_RX_A_OUT : out std_logic_vector(7 downto 0); -- memory block counter for PP/RDCMD + -- SPI interface + SPI_SCK_OUT : out std_logic; + SPI_CS_OUT : out std_logic; + SPI_SDI_IN : in std_logic; + SPI_SDO_OUT : out std_logic; + -- DEBUG + CLK_EN_OUT : out std_logic; + BSM_OUT : out std_logic_vector(7 downto 0); + DEBUG_OUT : out std_logic_vector(31 downto 0) + ); end entity; architecture Behavioral of spi_slim is --- new clock divider -signal div_counter : std_logic_vector(1+SLOW_SPI downto 0); -signal div_done_x : std_logic; -signal div_done : std_logic; -- same as clk_en -signal clk_en : std_logic; -- same as div_done - --- Statemachine signals -type state_t is (IDLE,CSL,TXCMD,TXADD_H,TXADD_M,TXADD_L,TXDATA,RXDATA, - WAIT1,WAIT2,WAIT3,WAIT4,WAIT5,WAIT6,WAIT7,WAIT8,CSH); -signal STATE, NEXT_STATE : state_t; - -signal rx_ena_x : std_logic; -signal rx_ena : std_logic; -signal tx_ena_x : std_logic; -signal tx_ena : std_logic; -signal busy_x : std_logic; -signal busy : std_logic; -signal spi_cs_x : std_logic; -- SPI chip select (low active) -signal spi_cs : std_logic; -signal spi_sck_x : std_logic; -- SPI clock (rising edge active, from counter) -signal spi_sck : std_logic; -signal tx_load_x : std_logic; -- load TX shift register -signal tx_load : std_logic; -signal tx_done_x : std_logic; -- one memory byte sent -signal tx_done : std_logic; -signal tx_sel_x : std_logic_vector(2 downto 0); -- select TX content -signal tx_sel : std_logic_vector(2 downto 0); -signal rx_store_x : std_logic; -- store RX shift register -signal rx_store : std_logic; -signal rx_complete : std_logic; -signal rst_addr_x : std_logic; -- reset address counter -signal rst_addr : std_logic; - -signal inc_addr_rx_x : std_logic; -signal inc_addr_rx : std_logic; -signal inc_addr_tx_x : std_logic; -signal inc_addr_tx : std_logic; -signal ce_addr_x : std_logic; -signal ce_addr : std_logic; - -signal addr_ctr : std_logic_vector(7 downto 0); -signal data_done_x : std_logic; -signal data_done : std_logic_vector(5 downto 0); - -signal last_tx_bit_x : std_logic; -signal last_tx_bit : std_logic; -signal is_data_x : std_logic; -signal is_data : std_logic; - --- debug signals -signal bsm_x : std_logic_vector(7 downto 0); -signal debug_x : std_logic_vector(31 downto 0); - -signal start : std_logic; -- buffered start_in signal, as we have a clocked down state machine -signal cmd_int : std_logic_vector(7 downto 0); -- internal command and address bytes -signal adh_int : std_logic_vector(7 downto 0); -- internal command and address bytes -signal adm_int : std_logic_vector(7 downto 0); -- internal command and address bytes -signal adl_int : std_logic_vector(7 downto 0); -- internal command and address bytes -signal max_int : std_logic_vector(7 downto 0); - --- transmitter -signal tx_sreg : std_logic_vector(7 downto 0); -signal tx_reg_comb : std_logic_vector(7 downto 0); -- multiplexer -signal tx_bit_cnt : std_logic_vector(3 downto 0); - --- receiver -signal rx_sreg : std_logic_vector(7 downto 0); -signal rx_bit_cnt_clr : std_logic; -signal rx_bit_cnt : std_logic_vector(3 downto 0); - --- registers -signal rx_data : std_logic_vector(7 downto 0); - --- FLASH commands --- single byte commands -constant NOP : std_logic_vector(7 downto 0) := x"FF"; -- no cmd to execute -constant WREN : std_logic_vector(7 downto 0) := x"06"; -- write enable -- OK -- CMD -constant WRDI : std_logic_vector(7 downto 0) := x"04"; -- write disable -- OK -- CMD -constant ERASE : std_logic_vector(7 downto 0) := x"C7"; -- chip erase -- OK -- CMD -constant DPD : std_logic_vector(7 downto 0) := x"b9"; -- deep powerdown -- OK -- CMD -constant RDPD : std_logic_vector(7 downto 0) := x"ab"; -- resume powerdown -- OK -- CMD - -constant RDID : std_logic_vector(7 downto 0) := x"9f"; -- read signature -- OK -- CMD + readbyte(n) -constant RDSR : std_logic_vector(7 downto 0) := x"05"; -- read status reg -- OK -- CMD + readbyte(n) - -constant WRSR : std_logic_vector(7 downto 0) := x"01"; -- write stat. reg -- OK -- CMD + writebyte(1) - -constant SE64 : std_logic_vector(7 downto 0) := x"d8"; -- sector erase 64kB -- OK -- CMD + ADH + ADM + ADL -constant SE32 : std_logic_vector(7 downto 0) := x"52"; -- sector erase 32kB -- OK -- CMD + ADH + ADM + ADL -constant SE4 : std_logic_vector(7 downto 0) := x"20"; -- sector erase 32kB -- OK -- CMD + ADH + ADM + ADL -constant SECP : std_logic_vector(7 downto 0) := x"36"; -- sector protect -- OK -- CMD + ADH + ADM + ADL -constant SECU : std_logic_vector(7 downto 0) := x"39"; -- sector unprotect -- OK -- CMD + ADH + ADM + ADL - -constant RDCMD : std_logic_vector(7 downto 0) := x"03"; -- read data -- OK -- CMD + ADH + ADM + ADL + readbyte(n) -constant RDSPR : std_logic_vector(7 downto 0) := x"3c"; -- read sect. prot. -- -- CMD + ADH + ADM + ADL + readbye(n) -constant PP : std_logic_vector(7 downto 0) := x"02"; -- page program -- OK -- CMD + ADH + ADM + ADL + writebyte(n) - + -- new clock divider + signal div_counter : std_logic_vector(1+SLOW_SPI downto 0); + signal div_done_x : std_logic; + signal div_done : std_logic; -- same as clk_en + signal clk_en : std_logic; -- same as div_done + + -- Statemachine signals + type state_t is (IDLE,CSL,TXCMD,TXADD_H,TXADD_M,TXADD_L,TXDATA,RXDATA, + WAIT1,WAIT2,WAIT3,WAIT4,WAIT5,WAIT6,WAIT7,WAIT8,CSH); + signal STATE, NEXT_STATE : state_t; + + signal rx_ena_x : std_logic; + signal rx_ena : std_logic; + signal tx_ena_x : std_logic; + signal tx_ena : std_logic; + signal busy_x : std_logic; + signal busy : std_logic; + signal spi_cs_x : std_logic; -- SPI chip select (low active) + signal spi_cs : std_logic; + signal spi_sck_x : std_logic; -- SPI clock (rising edge active, from counter) + signal spi_sck : std_logic; + signal tx_load_x : std_logic; -- load TX shift register + signal tx_load : std_logic; + signal tx_done_x : std_logic; -- one memory byte sent + signal tx_done : std_logic; + signal tx_sel_x : std_logic_vector(2 downto 0); -- select TX content + signal tx_sel : std_logic_vector(2 downto 0); + signal rx_store_x : std_logic; -- store RX shift register + signal rx_store : std_logic; + signal rx_complete : std_logic; + signal rst_addr_x : std_logic; -- reset address counter + signal rst_addr : std_logic; + + signal inc_addr_rx_x : std_logic; + signal inc_addr_rx : std_logic; + signal inc_addr_tx_x : std_logic; + signal inc_addr_tx : std_logic; + signal ce_addr_x : std_logic; + signal ce_addr : std_logic; + + signal addr_ctr : std_logic_vector(7 downto 0); + signal data_done_x : std_logic; + signal data_done : std_logic_vector(5 downto 0); + + signal last_tx_bit_x : std_logic; + signal last_tx_bit : std_logic; + signal is_data_x : std_logic; + signal is_data : std_logic; + + -- debug signals + signal bsm_x : std_logic_vector(7 downto 0); + signal debug_x : std_logic_vector(31 downto 0); + + signal start : std_logic; -- buffered start_in signal, as we have a clocked down state machine + signal cmd_int : std_logic_vector(7 downto 0); -- internal command and address bytes + signal adh_int : std_logic_vector(7 downto 0); -- internal command and address bytes + signal adm_int : std_logic_vector(7 downto 0); -- internal command and address bytes + signal adl_int : std_logic_vector(7 downto 0); -- internal command and address bytes + signal max_int : std_logic_vector(7 downto 0); + + -- transmitter + signal tx_sreg : std_logic_vector(7 downto 0); + signal tx_reg_comb : std_logic_vector(7 downto 0); -- multiplexer + signal tx_bit_cnt : std_logic_vector(3 downto 0); + + -- receiver + signal rx_sreg : std_logic_vector(7 downto 0); + signal rx_bit_cnt_clr : std_logic; + signal rx_bit_cnt : std_logic_vector(3 downto 0); + + -- registers + signal rx_data : std_logic_vector(7 downto 0); + + -- FLASH commands + -- single byte commands + constant NOP : std_logic_vector(7 downto 0) := x"FF"; -- no cmd to execute + constant WREN : std_logic_vector(7 downto 0) := x"06"; -- write enable -- OK -- CMD + constant WRDI : std_logic_vector(7 downto 0) := x"04"; -- write disable -- OK -- CMD + constant ERASE : std_logic_vector(7 downto 0) := x"C7"; -- chip erase -- OK -- CMD + constant DPD : std_logic_vector(7 downto 0) := x"b9"; -- deep powerdown -- OK -- CMD + constant RDPD : std_logic_vector(7 downto 0) := x"ab"; -- resume powerdown -- OK -- CMD + + constant RDID : std_logic_vector(7 downto 0) := x"9f"; -- read signature -- OK -- CMD + readbyte(n) + constant RDSR : std_logic_vector(7 downto 0) := x"05"; -- read status reg -- OK -- CMD + readbyte(n) + + constant WRSR : std_logic_vector(7 downto 0) := x"01"; -- write stat. reg -- OK -- CMD + writebyte(1) + + constant SE64 : std_logic_vector(7 downto 0) := x"d8"; -- sector erase 64kB -- OK -- CMD + ADH + ADM + ADL + constant SE32 : std_logic_vector(7 downto 0) := x"52"; -- sector erase 32kB -- OK -- CMD + ADH + ADM + ADL + constant SE4 : std_logic_vector(7 downto 0) := x"20"; -- sector erase 32kB -- OK -- CMD + ADH + ADM + ADL + constant SECP : std_logic_vector(7 downto 0) := x"36"; -- sector protect -- OK -- CMD + ADH + ADM + ADL + constant SECU : std_logic_vector(7 downto 0) := x"39"; -- sector unprotect -- OK -- CMD + ADH + ADM + ADL + + constant RDCMD : std_logic_vector(7 downto 0) := x"03"; -- read data -- OK -- CMD + ADH + ADM + ADL + readbyte(n) + constant RDSPR : std_logic_vector(7 downto 0) := x"3c"; -- read sect. prot. -- -- CMD + ADH + ADM + ADL + readbye(n) + constant PP : std_logic_vector(7 downto 0) := x"02"; -- page program -- OK -- CMD + ADH + ADM + ADL + writebyte(n) begin @@ -172,19 +171,19 @@ debug_x(2 downto 0) <= tx_sel; ----------------------------------------------------------- -- SPI clock generator ----------------------------------------------------------- -THE_CLOCK_DIVIDER: process(sysclk) +THE_CLOCK_DIVIDER: process( SYSCLK ) begin - if( rising_edge(sysclk) ) then - if( reset = '1' ) then - div_counter <= (others => '0'); - div_done <= '0'; - spi_sck <= spi_sck_x;--'0'; - else - div_counter <= div_counter + 1; - div_done <= div_done_x; - spi_sck <= spi_sck_x; - end if; + if( rising_edge(SYSCLK) ) then + if( RESET = '1' ) then + div_counter <= (others => '0'); + div_done <= '0'; + spi_sck <= spi_sck_x;--'0'; + else + div_counter <= div_counter + 1; + div_done <= div_done_x; + spi_sck <= spi_sck_x; end if; + end if; end process THE_CLOCK_DIVIDER; div_done_x <= '1' when ( or_all(div_counter) = '0' ) else '0'; @@ -197,61 +196,61 @@ clk_en <= div_done; ----------------------------------------------------------- -- start signal and local register sets for CMD and ADR ----------------------------------------------------------- -THE_START_PROC: process(sysclk) +THE_START_PROC: process( SYSCLK ) begin - if( rising_edge(sysclk) ) then - if ( reset = '1' ) then - start <= '0'; - cmd_int <= (others => '0'); - adh_int <= (others => '0'); - adm_int <= (others => '0'); - adl_int <= (others => '0'); - max_int <= (others => '0'); - elsif( (start_in = '1') and (busy = '0') ) then - start <= '1'; - cmd_int <= cmd_in; - adh_int <= adh_in; - adm_int <= adm_in; - adl_int <= adl_in; - max_int <= max_in; - elsif( busy = '1' ) then - start <= '0'; - end if; + if( rising_edge(SYSCLK) ) then + if ( RESET = '1' ) then + start <= '0'; + cmd_int <= (others => '0'); + adh_int <= (others => '0'); + adm_int <= (others => '0'); + adl_int <= (others => '0'); + max_int <= (others => '0'); + elsif( (START_IN = '1') and (busy = '0') ) then + start <= '1'; + cmd_int <= cmd_in; + adh_int <= adh_in; + adm_int <= adm_in; + adl_int <= adl_in; + max_int <= max_in; + elsif( busy = '1' ) then + start <= '0'; end if; + end if; end process THE_START_PROC; ----------------------------------------------------------- -- statemachine: clocked process ----------------------------------------------------------- -THE_STATEMACHINE: process( sysclk ) +THE_STATEMACHINE: process( SYSCLK ) begin - if( rising_edge(sysclk) ) then - if ( reset = '1' ) then - STATE <= IDLE; - rx_ena <= '0'; - tx_ena <= '0'; - busy <= '0'; - spi_cs <= spi_cs_x;--'1'; - tx_load <= '0'; - tx_sel <= "000"; - rx_store <= '0'; - rst_addr <= '0'; - tx_done <= '0'; - is_data <= '0'; - elsif( clk_en = '1' ) then - STATE <= NEXT_STATE; - rx_ena <= rx_ena_x; - tx_ena <= tx_ena_x; - busy <= busy_x; - spi_cs <= spi_cs_x; - tx_load <= tx_load_x; - tx_sel <= tx_sel_x; - rx_store <= rx_store_x; - rst_addr <= rst_addr_x; - tx_done <= tx_done_x; - is_data <= is_data_x; - end if; + if( rising_edge(SYSCLK) ) then + if ( RESET = '1' ) then + STATE <= IDLE; + rx_ena <= '0'; + tx_ena <= '0'; + busy <= '0'; + spi_cs <= spi_cs_x;--'1'; + tx_load <= '0'; + tx_sel <= "000"; + rx_store <= '0'; + rst_addr <= '0'; + tx_done <= '0'; + is_data <= '0'; + elsif( clk_en = '1' ) then + STATE <= NEXT_STATE; + rx_ena <= rx_ena_x; + tx_ena <= tx_ena_x; + busy <= busy_x; + spi_cs <= spi_cs_x; + tx_load <= tx_load_x; + tx_sel <= tx_sel_x; + rx_store <= rx_store_x; + rst_addr <= rst_addr_x; + tx_done <= tx_done_x; + is_data <= is_data_x; end if; + end if; end process THE_STATEMACHINE; ----------------------------------------------------------- @@ -259,291 +258,304 @@ end process THE_STATEMACHINE; ----------------------------------------------------------- THE_STATE_TRANSITIONS: process( STATE, cmd_int, start, tx_bit_cnt, rx_bit_cnt, data_done(5) ) begin - rx_ena_x <= '0'; - tx_ena_x <= '0'; - busy_x <= '1'; - spi_cs_x <= '1'; - tx_load_x <= '0'; - tx_sel_x <= "000"; - rx_store_x <= '0'; - rst_addr_x <= '0'; - tx_done_x <= '0'; - is_data_x <= '0'; - case STATE is - when IDLE => - if( start = '1' ) then - NEXT_STATE <= CSL; - spi_cs_x <= '0'; - tx_load_x <= '1'; - tx_sel_x <= "000"; - rst_addr_x <= '1'; - else - NEXT_STATE <= IDLE; - busy_x <= '0'; - end if; - - when CSL => - NEXT_STATE <= TXCMD; - tx_ena_x <= '1'; - spi_cs_x <= '0'; - - when TXCMD => - if( tx_bit_cnt < x"7" ) then - NEXT_STATE <= TXCMD; - tx_ena_x <= '1'; - spi_cs_x <= '0'; - else - case cmd_int is - when WREN | WRDI | ERASE | DPD | RDPD - => NEXT_STATE <= CSH; - spi_cs_x <= '0'; - when SE64 | SE32 | SE4 | PP | RDCMD | SECP | SECU | RDSPR - => NEXT_STATE <= WAIT1; - spi_cs_x <= '0'; - tx_load_x <= '1'; - tx_sel_x <= "001"; -- ADH - when WRSR => NEXT_STATE <= WAIT1; - spi_cs_x <= '0'; - tx_load_x <= '1'; - tx_sel_x <= "100"; -- TXDATA - is_data_x <= '1'; - when RDSR | RDID - => NEXT_STATE <= WAIT1; - spi_cs_x <= '0'; - tx_load_x <= '1'; - tx_sel_x <= "110"; -- "00" - when others => NEXT_STATE <= CSH; - spi_cs_x <= '0'; - end case; - end if; - - when WAIT1 => - case cmd_int is - when SE64 | SE32 | SE4 | PP | RDCMD | SECP | SECU | RDSPR - => NEXT_STATE <= TXADD_H; - tx_ena_x <= '1'; - spi_cs_x <= '0'; - when RDSR | RDID - => NEXT_STATE <= RXDATA; - rx_ena_x <= '1'; - spi_cs_x <= '0'; - when WRSR => NEXT_STATE <= TXDATA; - tx_ena_x <= '1'; - spi_cs_x <= '0'; - is_data_x <= '1'; - when others => NEXT_STATE <= CSH; - spi_cs_x <= '0'; - end case; - - when TXADD_H => - if( tx_bit_cnt < x"7" ) then - NEXT_STATE <= TXADD_H; - tx_ena_x <= '1'; - spi_cs_x <= '0'; - else - NEXT_STATE <= WAIT2; - spi_cs_x <= '0'; - tx_load_x <= '1'; - tx_sel_x <= "010"; -- ADM - end if; - - when WAIT2 => - NEXT_STATE <= TXADD_M; - tx_ena_x <= '1'; - spi_cs_x <= '0'; - - when TXADD_M => - if( tx_bit_cnt < x"7" ) then - NEXT_STATE <= TXADD_M; - tx_ena_x <= '1'; - spi_cs_x <= '0'; - else - NEXT_STATE <= WAIT3; - spi_cs_x <= '0'; - tx_load_x <= '1'; - tx_sel_x <= "011"; -- ADL - end if; - - when WAIT3 => - NEXT_STATE <= TXADD_L; - tx_ena_x <= '1'; - spi_cs_x <= '0'; - - when TXADD_L => - if( tx_bit_cnt < x"7" ) then - NEXT_STATE <= TXADD_L; - tx_ena_x <= '1'; - spi_cs_x <= '0'; - else - case cmd_int is - when PP => NEXT_STATE <= WAIT6; - tx_load_x <= '1'; - tx_sel_x <= "100"; -- TXDATA - spi_cs_x <= '0'; - when SE64 | SE32 | SE4 | SECP | SECU - => NEXT_STATE <= CSH; - spi_cs_x <= '0'; - when RDCMD | RDSPR - => NEXT_STATE <= WAIT4; - spi_cs_x <= '0'; - tx_load_x <= '1'; - tx_sel_x <= "110"; -- "00" - when others => NEXT_STATE <= CSH; - spi_cs_x <= '0'; - end case; - end if; - - when WAIT4 => - case cmd_int is - when RDCMD | RDSPR - => NEXT_STATE <= RXDATA; - rx_ena_x <= '1'; - spi_cs_x <= '0'; - when others => NEXT_STATE <= CSH; - spi_cs_x <= '0'; - end case; - - when RXDATA => - if( rx_bit_cnt < x"7" ) then - NEXT_STATE <= RXDATA; - rx_ena_x <= '1'; - spi_cs_x <= '0'; - else - case cmd_int is - when RDCMD | RDSR | RDID | RDSPR - => NEXT_STATE <= WAIT7; - spi_cs_x <= '0'; - rx_store_x <= '1'; - when others => NEXT_STATE <= CSH; - spi_cs_x <= '0'; - rx_store_x <= '1'; - end case; - end if; - - when WAIT6 => - case cmd_int is - when PP => if( data_done(5) = '1' ) then - NEXT_STATE <= CSH; - spi_cs_x <= '0'; - else - NEXT_STATE <= TXDATA; - tx_ena_x <= '1'; - spi_cs_x <= '0'; - is_data_x <= '1'; - end if; - when others => NEXT_STATE <= CSH; - spi_cs_x <= '0'; - end case; - - when TXDATA => - if( tx_bit_cnt < x"7" ) then - NEXT_STATE <= TXDATA; - tx_ena_x <= '1'; - spi_cs_x <= '0'; - else - case cmd_int is - when PP => NEXT_STATE <= WAIT6; - spi_cs_x <= '0'; - tx_done_x <= '1'; - tx_load_x <= '1'; - tx_sel_x <= "100"; -- TXDATA - when others => NEXT_STATE <= CSH; - spi_cs_x <= '0'; - end case; - end if; - is_data_x <= '1'; - - when WAIT7 => - NEXT_STATE <= WAIT8; - spi_cs_x <= '0'; - - when WAIT8 => - case cmd_int is - when RDCMD | RDID | RDSR | RDSPR - => if( data_done(5) = '1' ) then - NEXT_STATE <= CSH; - spi_cs_x <= '0'; - else - NEXT_STATE <= RXDATA; - rx_ena_x <= '1'; - spi_cs_x <= '0'; - end if; - when others => NEXT_STATE <= CSH; - spi_cs_x <= '0'; - end case; - - when WAIT5 => - NEXT_STATE <= CSH; - spi_cs_x <= '0'; - - when CSH => - NEXT_STATE <= IDLE; - busy_x <= '0'; + rx_ena_x <= '0'; + tx_ena_x <= '0'; + busy_x <= '1'; + spi_cs_x <= '1'; + tx_load_x <= '0'; + tx_sel_x <= "000"; + rx_store_x <= '0'; + rst_addr_x <= '0'; + tx_done_x <= '0'; + is_data_x <= '0'; + case STATE is + when IDLE => + if( start = '1' ) then + NEXT_STATE <= CSL; + spi_cs_x <= '0'; + tx_load_x <= '1'; + tx_sel_x <= "000"; + rst_addr_x <= '1'; + else + NEXT_STATE <= IDLE; + busy_x <= '0'; + end if; + + when CSL => + NEXT_STATE <= TXCMD; + tx_ena_x <= '1'; + spi_cs_x <= '0'; + + when TXCMD => + if( tx_bit_cnt < x"7" ) then + NEXT_STATE <= TXCMD; + tx_ena_x <= '1'; + spi_cs_x <= '0'; + else + case cmd_int is + when WREN | WRDI | ERASE | DPD | RDPD + => NEXT_STATE <= CSH; + spi_cs_x <= '0'; + when SE64 | SE32 | SE4 | PP | RDCMD | SECP | SECU | RDSPR + => NEXT_STATE <= WAIT1; + spi_cs_x <= '0'; + tx_load_x <= '1'; + tx_sel_x <= "001"; -- ADH + when WRSR + => NEXT_STATE <= WAIT1; + spi_cs_x <= '0'; + tx_load_x <= '1'; + tx_sel_x <= "100"; -- TXDATA + is_data_x <= '1'; + when RDSR | RDID + => NEXT_STATE <= WAIT1; + spi_cs_x <= '0'; + tx_load_x <= '1'; + tx_sel_x <= "110"; -- "00" + when others + => NEXT_STATE <= CSH; + spi_cs_x <= '0'; + end case; + end if; - end case; + when WAIT1 => + case cmd_int is + when SE64 | SE32 | SE4 | PP | RDCMD | SECP | SECU | RDSPR + => NEXT_STATE <= TXADD_H; + tx_ena_x <= '1'; + spi_cs_x <= '0'; + when RDSR | RDID + => NEXT_STATE <= RXDATA; + rx_ena_x <= '1'; + spi_cs_x <= '0'; + when WRSR + => NEXT_STATE <= TXDATA; + tx_ena_x <= '1'; + spi_cs_x <= '0'; + is_data_x <= '1'; + when others + => NEXT_STATE <= CSH; + spi_cs_x <= '0'; + end case; + + when TXADD_H => + if( tx_bit_cnt < x"7" ) then + NEXT_STATE <= TXADD_H; + tx_ena_x <= '1'; + spi_cs_x <= '0'; + else + NEXT_STATE <= WAIT2; + spi_cs_x <= '0'; + tx_load_x <= '1'; + tx_sel_x <= "010"; -- ADM + end if; + + when WAIT2 => + NEXT_STATE <= TXADD_M; + tx_ena_x <= '1'; + spi_cs_x <= '0'; + + when TXADD_M => + if( tx_bit_cnt < x"7" ) then + NEXT_STATE <= TXADD_M; + tx_ena_x <= '1'; + spi_cs_x <= '0'; + else + NEXT_STATE <= WAIT3; + spi_cs_x <= '0'; + tx_load_x <= '1'; + tx_sel_x <= "011"; -- ADL + end if; + + when WAIT3 => + NEXT_STATE <= TXADD_L; + tx_ena_x <= '1'; + spi_cs_x <= '0'; + + when TXADD_L => + if( tx_bit_cnt < x"7" ) then + NEXT_STATE <= TXADD_L; + tx_ena_x <= '1'; + spi_cs_x <= '0'; + else + case cmd_int is + when PP + => NEXT_STATE <= WAIT6; + tx_load_x <= '1'; + tx_sel_x <= "100"; -- TXDATA + spi_cs_x <= '0'; + when SE64 | SE32 | SE4 | SECP | SECU + => NEXT_STATE <= CSH; + spi_cs_x <= '0'; + when RDCMD | RDSPR + => NEXT_STATE <= WAIT4; + spi_cs_x <= '0'; + tx_load_x <= '1'; + tx_sel_x <= "110"; -- "00" + when others + => NEXT_STATE <= CSH; + spi_cs_x <= '0'; + end case; + end if; + + when WAIT4 => + case cmd_int is + when RDCMD | RDSPR + => NEXT_STATE <= RXDATA; + rx_ena_x <= '1'; + spi_cs_x <= '0'; + when others + => NEXT_STATE <= CSH; + spi_cs_x <= '0'; + end case; + + when RXDATA => + if( rx_bit_cnt < x"7" ) then + NEXT_STATE <= RXDATA; + rx_ena_x <= '1'; + spi_cs_x <= '0'; + else + case cmd_int is + when RDCMD | RDSR | RDID | RDSPR + => NEXT_STATE <= WAIT7; + spi_cs_x <= '0'; + rx_store_x <= '1'; + when others + => NEXT_STATE <= CSH; + spi_cs_x <= '0'; + rx_store_x <= '1'; + end case; + end if; + + when WAIT6 => + case cmd_int is + when PP + => if( data_done(5) = '1' ) then + NEXT_STATE <= CSH; + spi_cs_x <= '0'; + else + NEXT_STATE <= TXDATA; + tx_ena_x <= '1'; + spi_cs_x <= '0'; + is_data_x <= '1'; + end if; + when others + => NEXT_STATE <= CSH; + spi_cs_x <= '0'; + end case; + + when TXDATA => + if( tx_bit_cnt < x"7" ) then + NEXT_STATE <= TXDATA; + tx_ena_x <= '1'; + spi_cs_x <= '0'; + else + case cmd_int is + when PP + => NEXT_STATE <= WAIT6; + spi_cs_x <= '0'; + tx_done_x <= '1'; + tx_load_x <= '1'; + tx_sel_x <= "100"; -- TXDATA + when others + => NEXT_STATE <= CSH; + spi_cs_x <= '0'; + end case; + end if; + is_data_x <= '1'; + + when WAIT7 => + NEXT_STATE <= WAIT8; + spi_cs_x <= '0'; + + when WAIT8 => + case cmd_int is + when RDCMD | RDID | RDSR | RDSPR + => if( data_done(5) = '1' ) then + NEXT_STATE <= CSH; + spi_cs_x <= '0'; + else + NEXT_STATE <= RXDATA; + rx_ena_x <= '1'; + spi_cs_x <= '0'; + end if; + when others + => NEXT_STATE <= CSH; + spi_cs_x <= '0'; + end case; + + when WAIT5 => + NEXT_STATE <= CSH; + spi_cs_x <= '0'; + + when CSH => + NEXT_STATE <= IDLE; + busy_x <= '0'; + + end case; end process THE_STATE_TRANSITIONS; -- state machine output table THE_STATEMACHINE_OUT: process( STATE ) begin - -- default values - rx_bit_cnt_clr <= '1'; - - case STATE is - when IDLE => bsm_x <= x"00"; - when CSL => bsm_x <= x"09"; - when TXCMD => bsm_x <= x"01"; - when TXDATA => bsm_x <= x"02"; - when TXADD_H => bsm_x <= x"03"; - when TXADD_M => bsm_x <= x"04"; - when TXADD_L => bsm_x <= x"05"; - when RXDATA => bsm_x <= x"07"; - when WAIT1 => bsm_x <= x"10"; - when WAIT2 => bsm_x <= x"11"; - when WAIT3 => bsm_x <= x"12"; - when WAIT4 => bsm_x <= x"13"; - when WAIT8 => bsm_x <= x"17"; - when WAIT6 => bsm_x <= x"15"; - when WAIT5 => bsm_x <= x"14"; - when WAIT7 => bsm_x <= x"16"; - when CSH => bsm_x <= x"08"; - when others => bsm_x <= x"ff"; - end case; + -- default values + rx_bit_cnt_clr <= '1'; + + case STATE is + when IDLE => bsm_x <= x"00"; + when CSL => bsm_x <= x"09"; + when TXCMD => bsm_x <= x"01"; + when TXDATA => bsm_x <= x"02"; + when TXADD_H => bsm_x <= x"03"; + when TXADD_M => bsm_x <= x"04"; + when TXADD_L => bsm_x <= x"05"; + when RXDATA => bsm_x <= x"07"; + when WAIT1 => bsm_x <= x"10"; + when WAIT2 => bsm_x <= x"11"; + when WAIT3 => bsm_x <= x"12"; + when WAIT4 => bsm_x <= x"13"; + when WAIT8 => bsm_x <= x"17"; + when WAIT6 => bsm_x <= x"15"; + when WAIT5 => bsm_x <= x"14"; + when WAIT7 => bsm_x <= x"16"; + when CSH => bsm_x <= x"08"; + when others => bsm_x <= x"ff"; + end case; end process THE_STATEMACHINE_OUT; -- TX data register multiplexer THE_TXREG_MUX: process( tx_sel, cmd_int, adh_int, adm_int, adl_int, txdata_in ) begin - case tx_sel is - when "000" => tx_reg_comb <= cmd_int; - when "001" => tx_reg_comb <= adh_int; - when "010" => tx_reg_comb <= adm_int; - when "011" => tx_reg_comb <= adl_int; - when "100" => tx_reg_comb <= txdata_in; - when "101" => tx_reg_comb <= x"ee"; -- unused - when "110" => tx_reg_comb <= x"00"; -- fixed value - when "111" => tx_reg_comb <= x"aa"; -- fixed value - when others => tx_reg_comb <= x"00"; - end case; + case tx_sel is + when "000" => tx_reg_comb <= cmd_int; + when "001" => tx_reg_comb <= adh_int; + when "010" => tx_reg_comb <= adm_int; + when "011" => tx_reg_comb <= adl_int; + when "100" => tx_reg_comb <= txdata_in; + when "101" => tx_reg_comb <= x"ee"; -- unused + when "110" => tx_reg_comb <= x"00"; -- fixed value + when "111" => tx_reg_comb <= x"aa"; -- fixed value + when others => tx_reg_comb <= x"00"; + end case; end process THE_TXREG_MUX; -- TXData shift register and bit counter THE_TX_SHIFT_AND_BITCOUNT: process( sysclk ) begin - if( rising_edge(sysclk) ) then - if( reset = '1' ) then - tx_sreg(6 downto 0) <= (others => '0'); - tx_bit_cnt <= (others => '0'); - last_tx_bit <= '0'; - elsif ( (clk_en = '1' ) and (tx_load = '1') ) then - tx_bit_cnt <= (others => '0'); - tx_sreg <= tx_reg_comb; - elsif( (clk_en = '1') and (tx_ena = '1') ) then - tx_bit_cnt <= tx_bit_cnt + 1; - tx_sreg <= tx_sreg (6 downto 0) & '0'; - end if; - last_tx_bit <= last_tx_bit_x; + if( rising_edge(sysclk) ) then + if( reset = '1' ) then + tx_sreg(6 downto 0) <= (others => '0'); + tx_bit_cnt <= (others => '0'); + last_tx_bit <= '0'; + elsif ( (clk_en = '1' ) and (tx_load = '1') ) then + tx_bit_cnt <= (others => '0'); + tx_sreg <= tx_reg_comb; + elsif( (clk_en = '1') and (tx_ena = '1') ) then + tx_bit_cnt <= tx_bit_cnt + 1; + tx_sreg <= tx_sreg (6 downto 0) & '0'; end if; + last_tx_bit <= last_tx_bit_x; + end if; end process THE_TX_SHIFT_AND_BITCOUNT; last_tx_bit_x <= '1' when ( tx_bit_cnt = x"7" ) else '0'; @@ -551,59 +563,59 @@ last_tx_bit_x <= '1' when ( tx_bit_cnt = x"7" ) else '0'; -- receiver shift register and bit counter THE_RX_SHIFT_AND_BITCOUNT: process( sysclk ) begin - if( rising_edge(sysclk) ) then - if ( reset = '1' ) then - rx_bit_cnt <= (others => '0'); - rx_sreg <= (others => '0'); - elsif( (clk_en = '1') and (rx_ena = '1') ) then - rx_sreg <= rx_sreg (6 downto 0) & spi_sdi_in; - case rx_bit_cnt is - when x"0" | x"1" | x"2" | x"3" | x"4" | x"5" | x"6" => - rx_bit_cnt <= rx_bit_cnt + 1; - when x"7" => - rx_bit_cnt <= (others => '0'); - when others => - null; - end case; - end if; + if( rising_edge(sysclk) ) then + if ( reset = '1' ) then + rx_bit_cnt <= (others => '0'); + rx_sreg <= (others => '0'); + elsif( (clk_en = '1') and (rx_ena = '1') ) then + rx_sreg <= rx_sreg (6 downto 0) & spi_sdi_in; + case rx_bit_cnt is + when x"0" | x"1" | x"2" | x"3" | x"4" | x"5" | x"6" => + rx_bit_cnt <= rx_bit_cnt + 1; + when x"7" => + rx_bit_cnt <= (others => '0'); + when others => + null; + end case; end if; + end if; end process THE_RX_SHIFT_AND_BITCOUNT; -- the rx_data register THE_RXDATA_REG: process( sysclk ) begin - if( rising_edge(sysclk) ) then - if ( reset = '1' ) then - rx_data <= (others => '0'); - rx_complete <= '0'; - elsif( (clk_en = '1') and (rx_store = '1') ) then - rx_data <= rx_sreg; - rx_complete <= '1'; - else - rx_complete <= '0'; - end if; + if( rising_edge(sysclk) ) then + if ( reset = '1' ) then + rx_data <= (others => '0'); + rx_complete <= '0'; + elsif( (clk_en = '1') and (rx_store = '1') ) then + rx_data <= rx_sreg; + rx_complete <= '1'; + else + rx_complete <= '0'; end if; + end if; end process; -- address generator for external BRAM THE_ADDR_COUNTER: process( sysclk ) begin - if( rising_edge(sysclk) ) then - if ( (reset = '1') or (rst_addr = '1') ) then - addr_ctr <= (others => '0'); - data_done <= (others => '0'); - inc_addr_rx <= '0'; - inc_addr_tx <= '0'; - ce_addr <= '0'; - elsif( ce_addr = '1' ) then - addr_ctr <= addr_ctr + 1; - end if; - data_done(5 downto 1) <= data_done(4 downto 0); - data_done(0) <= data_done_x; - inc_addr_rx <= inc_addr_rx_x; - inc_addr_tx <= inc_addr_tx_x; - ce_addr <= ce_addr_x; + if( rising_edge(sysclk) ) then + if ( (reset = '1') or (rst_addr = '1') ) then + addr_ctr <= (others => '0'); + data_done <= (others => '0'); + inc_addr_rx <= '0'; + inc_addr_tx <= '0'; + ce_addr <= '0'; + elsif( ce_addr = '1' ) then + addr_ctr <= addr_ctr + 1; end if; + data_done(5 downto 1) <= data_done(4 downto 0); + data_done(0) <= data_done_x; + inc_addr_rx <= inc_addr_rx_x; + inc_addr_tx <= inc_addr_tx_x; + ce_addr <= ce_addr_x; + end if; end process THE_ADDR_COUNTER; inc_addr_rx_x <= '1' when ( rx_complete = '1' ) else '0'; @@ -614,19 +626,18 @@ ce_addr_x <= inc_addr_rx or inc_addr_tx; data_done_x <= '1' when ( addr_ctr = max_int ) else '0'; -- output signals -spi_cs_out <= spi_cs; -spi_sck_out <= spi_sck; -spi_sdo_out <= tx_sreg(7); -busy_out <= busy; - -tx_rd_out <= '0'; -rxdata_out <= rx_data; -rx_wr_out <= rx_complete; -tx_rx_a_out <= addr_ctr; - -clk_en_out <= clk_en; -bsm_out <= bsm_x; -debug_out <= debug_x; - +SPI_CS_OUT <= spi_cs; +SPI_SCK_OUT <= spi_sck; +SPI_SDO_OUT <= tx_sreg(7); +BUSY_OUT <= busy; + +TX_RD_OUT <= '0'; +RXDATA_OUT <= rx_data; +RX_WR_OUT <= rx_complete; +TX_RX_A_OUT <= addr_ctr; + +CLK_EN_OUT <= clk_en; +BSM_OUT <= bsm_x; +DEBUG_OUT <= debug_x; end Behavioral; diff --git a/trb_net16_endpoint_hades_full_handler_record.vhd b/trb_net16_endpoint_hades_full_handler_record.vhd index ccc18c6..43c738c 100644 --- a/trb_net16_endpoint_hades_full_handler_record.vhd +++ b/trb_net16_endpoint_hades_full_handler_record.vhd @@ -300,9 +300,17 @@ begin STAT_ONEWIRE => open, STAT_ADDR_DEBUG => open, STAT_TRIGGER_OUT => STAT_TRIGGER_OUT, - DEBUG_LVL1_HANDLER_OUT => DEBUG_LVL1_HANDLER_OUT + DEBUG_LVL1_HANDLER_OUT => open --DEBUG_LVL1_HANDLER_OUT ); +---- + DEBUG_LVL1_HANDLER_OUT(15 downto 4) <= (others => '0'); + DEBUG_LVL1_HANDLER_OUT(3) <= regio_tx.nack; + DEBUG_LVL1_HANDLER_OUT(2) <= regio_tx.ack; + DEBUG_LVL1_HANDLER_OUT(1) <= regio_rx.write; + DEBUG_LVL1_HANDLER_OUT(0) <= regio_rx.read; +---- + TIMERS_OUT.microsecond <= time_global_i; TIMERS_OUT.clock <= time_local_i; TIMERS_OUT.last_trigger <= time_since_last_trg_i; @@ -321,7 +329,7 @@ TIMERS_OUT.uid <= unique_id_i; generic map( PORT_NUMBER => 7, PORT_ADDRESSES => (0 => x"8000", 1 => x"7100", 2 => x"7110", 3 => x"7200", 4 => x"7300", 5 => x"8100", 6 => x"8300", others => x"0000"), - PORT_ADDR_MASK => (0 => 15, 1 => 4, 2 => 3, 3 => 2, 4 => 5, 5 => 8, 6 => 8, others => 0) + PORT_ADDR_MASK => (0 => 15, 1 => 4, 2 => 3, 3 => 2, 4 => 5, 5 => 8, 6 => 8, others => 0) ) port map( CLK => CLK, -- 2.43.0