From 75587a1d6a55aca4817ed813f6bbb34af320334e Mon Sep 17 00:00:00 2001 From: Jan Michel Date: Tue, 18 Jul 2017 18:35:13 +0200 Subject: [PATCH 1/1] add first files to generic VHDL repo --- interface/code/uart_rec.vhd | 160 +++++++++++++++++++++++++++ interface/code/uart_trans.vhd | 148 +++++++++++++++++++++++++ interface/spi_slave.vhd | 154 ++++++++++++++++++++++++++ interface/uart_sctrl.vhd | 198 +++++++++++++++++++++++++++++++++ io/pwm.vhd | 82 ++++++++++++++ machxo3/sedcheck.vhd | 201 ++++++++++++++++++++++++++++++++++ 6 files changed, 943 insertions(+) create mode 100644 interface/code/uart_rec.vhd create mode 100644 interface/code/uart_trans.vhd create mode 100644 interface/spi_slave.vhd create mode 100644 interface/uart_sctrl.vhd create mode 100644 io/pwm.vhd create mode 100644 machxo3/sedcheck.vhd diff --git a/interface/code/uart_rec.vhd b/interface/code/uart_rec.vhd new file mode 100644 index 0000000..f168832 --- /dev/null +++ b/interface/code/uart_rec.vhd @@ -0,0 +1,160 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + + + +entity uart_rec is +-- generic( +-- CLK_DIV : integer +-- ); + port( + CLK_DIV : in integer; + CLK : in std_logic; + RST : in std_logic; + RX : in std_logic; + + DATA_OUT : out std_logic_vector(7 downto 0); + DATA_WAITING : out std_logic; + DEBUG : out std_logic_vector(3 downto 0) + ); +end entity; + + + +architecture uart_rec_arch of uart_rec is + +signal clk_div_counter: unsigned(15 downto 0) := x"0000"; +signal symbol_pulse : std_logic := '0'; +signal symbol_counter: unsigned(3 downto 0) := x"0"; + +type state_type is (idle,receiving,update_parallel_output); +signal state: state_type := idle; + +-- MSB is the stopbit, LSB is the start bit, both are never changed +signal rx_shift_register: std_logic_vector(9 downto 0); +signal symbol : std_logic := '1'; +signal data_waiting_sig: std_logic := '0'; +signal current_data_out: std_logic_vector(7 downto 0) := "00000000"; +signal symbol_start_pulse : std_logic := '0'; -- just debug +signal rst_clk_div_counter : std_logic; +signal rx_reg : std_logic; + +begin +---------------------------- +-- debug +---------------------------- + +DEBUG(0) <= symbol_start_pulse; +DEBUG(1) <= symbol_pulse; +DEBUG(2) <= data_waiting_sig; +DEBUG(3) <= '0'; + +---------------------------- +-- Inputs +---------------------------- + sync_input : process begin + wait until rising_edge(CLK); + rx_reg <= RX; + symbol <= rx_reg; + end process; + +---------------------------- +-- Outputs +---------------------------- + sync_output : process begin + wait until rising_edge(CLK); + DATA_WAITING <= data_waiting_sig; + DATA_OUT <= current_data_out; + end process; + +---------------------------- +-- Generate Serial Clock +---------------------------- + clock_division : process begin + wait until rising_edge(CLK); + -- scaling down the main clock to the desired baudrate + if clk_div_counter = to_unsigned(CLK_DIV,16)-1 then + clk_div_counter <= x"0000"; + else + clk_div_counter <= clk_div_counter + 1; + end if; + -- generates symbol_pulse, a signal that has 1 clock cycle pulses, one symbol duration period apart + -- in contrast to the transceiver module, the symbol pulse is generated in the middle of the + -- symbol period + -- if clk_div_counter = '0' & CLK_DIV(15 downto 1) then -- CLK_DIV/2 by >> (right shifting) + if clk_div_counter = to_unsigned(CLK_DIV/2,16) then + symbol_pulse <= '1'; + else + symbol_pulse <= '0'; + end if; + + if clk_div_counter = x"0000" then + symbol_start_pulse <= '1'; + else + symbol_start_pulse <= '0'; + end if; + if (RST or rst_clk_div_counter) = '1' then + clk_div_counter <= x"0000"; + end if; + + end process; + +---------------------------- +-- State Machine of the Receiver +---------------------------- + state_machine : process begin + wait until rising_edge(CLK); + data_waiting_sig <= '0'; + rst_clk_div_counter <= '0'; + + -- state machine rules: + case state is + when idle => + rst_clk_div_counter<= '1'; + if symbol = '0' then -- the start bit comes! + state <= receiving; + -- restart the divcounter + -- clk_div_counter <= x"0000"; + symbol_counter <= x"0"; + + end if; + + when receiving => + if symbol_pulse = '1' then + if symbol_counter <= x"9" then -- reception process + rx_shift_register(to_integer(symbol_counter)) <= symbol; + symbol_counter <= symbol_counter + 1; + end if; + if symbol_counter = x"9" then + state <= update_parallel_output; + end if; + + + end if; + when update_parallel_output => + -- check start and stop bit consistency + -- (checking the start bit again seems a little obsolete) + -- only if bit was received correctly output the data! +-- if rx_shift_register(0) = '0' and rx_shift_register(9) = '1' then + if symbol = '1' then + state <= idle; + if rx_shift_register(0) = '0' and rx_shift_register(9) = '1' then + current_data_out <= rx_shift_register(8 downto 1); + data_waiting_sig <= '1'; + end if; + end if; + + end case; + + -- reset clock divider counters when reset signal is on + if RST = '1' then + symbol_counter <= x"0"; + data_waiting_sig <= '0'; + state <= idle; + end if; + + end process; + + +end architecture; \ No newline at end of file diff --git a/interface/code/uart_trans.vhd b/interface/code/uart_trans.vhd new file mode 100644 index 0000000..01967dc --- /dev/null +++ b/interface/code/uart_trans.vhd @@ -0,0 +1,148 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + + + +entity uart_trans is +-- generic( +-- CLK_DIV : integer +-- ); + port( + CLK_DIV : in integer; + CLK : in std_logic; + RST : in std_logic; + + DATA_IN : in std_logic_vector(7 downto 0); + SEND : in std_logic; + READY : out std_logic; + + TX : out std_logic; + DEBUG : out std_logic_vector(3 downto 0) + + ); +end entity; + + + +architecture uart_trans_arch of uart_trans is + + + +signal clk_div_counter: unsigned(15 downto 0) := x"0000"; +signal symbol_start_pulse : std_logic := '0'; +signal symbol_counter: unsigned(3 downto 0) := x"0"; + +type state_type is (idle,transmitting); +signal state: state_type := idle; + +-- MSB is the stopbit, LSB is the start bit, both are never changed +signal tx_shift_register: std_logic_vector(9 downto 0) := "1000000000"; +signal symbol: std_logic := '1'; +signal ready_sig: std_logic := '1'; +signal rst_clk_div_counter : std_logic; + + +begin +---------------------------- +-- debug +---------------------------- + +DEBUG(0) <= symbol_start_pulse; +DEBUG(1) <= '0'; +DEBUG(2) <= ready_sig; +DEBUG(3) <= '0'; + +---------------------------- +-- Inputs +---------------------------- +-- sync_input : process begin +-- wait until rising_edge(CLK); +-- synced_send <= SEND; +-- end process; +-- hard wired stuff + +---------------------------- +-- Outputs +---------------------------- + sync_output : process begin + wait until rising_edge(CLK); + TX <= symbol; + end process; + + READY <= ready_sig and not SEND; + +---------------------------- +-- Generate Serial Clock +---------------------------- + clock_division : process begin + wait until rising_edge(CLK); + -- scaling down the main clock to the desired baudrate + if clk_div_counter = to_unsigned(CLK_DIV,16)-1 then + clk_div_counter <= x"0000"; + else + clk_div_counter <= clk_div_counter + 1; + end if; + + + if clk_div_counter = x"0001" then + symbol_start_pulse <= '1'; + else + symbol_start_pulse <= '0'; + end if; + if (RST or rst_clk_div_counter) = '1' then + clk_div_counter <= x"0000"; + end if; + + end process; + +---------------------------- +-- State Machine of the Transmitter +---------------------------- + + state_machine : process begin + wait until rising_edge(CLK); + -- state machine rules: + rst_clk_div_counter <= '0'; + + case state is + when idle => + rst_clk_div_counter <= '1'; + ready_sig <= '1'; + if SEND = '1' then + state <= transmitting; + symbol_counter <= x"0"; + -- capture the byte at the parallel input + tx_shift_register <= '1' & DATA_IN & '0'; + ready_sig <= '0'; + end if; + + when transmitting => + if symbol_start_pulse = '1' then + if symbol_counter <= 9 then -- transmission process + symbol <= tx_shift_register(to_integer(symbol_counter)); + end if; + + symbol_counter <= symbol_counter + 1; + if symbol_counter = 10 then -- pulse #10 (1 start, 8 data, 1 stop) has been sent + --, time to go to idle mode again + -- pull the tx line high again, actually obsolete, because stop bit is 1 + symbol <= '1'; + state <= idle; + end if; + end if; + end case; + + -- reset clock divider counters when reset signal is on + if RST = '1' then + state <= idle; + ready_sig <= '1'; + symbol <= '1'; + end if; + + end process; + + + +end architecture; + diff --git a/interface/spi_slave.vhd b/interface/spi_slave.vhd new file mode 100644 index 0000000..f234756 --- /dev/null +++ b/interface/spi_slave.vhd @@ -0,0 +1,154 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +use work.trb_net_std.all; + + +entity spi_slave is + port( + CLK : in std_logic; + + SPI_CLK : in std_logic; + SPI_CS : in std_logic; + SPI_IN : in std_logic; + SPI_OUT : out std_logic; + + DATA_OUT : out std_logic_vector(15 downto 0); + DATA_IN : in std_logic_vector(15 downto 0); + ADDR_OUT : out std_logic_vector(7 downto 0); + WRITE_OUT : out std_logic; + READ_OUT : out std_logic; + READY_IN : in std_logic; + + DEBUG : out std_logic_vector(15 downto 0) + ); +end entity; + +architecture SPI_Slave_arch of spi_slave is +signal spi_clk_last : std_logic; +signal spi_clk_reg : std_logic; +signal spi_cs_reg : std_logic; +signal spi_in_reg : std_logic; + +signal operation_i : std_logic; +signal data_write : std_logic_vector(15 downto 0); +signal data_in_i : std_logic_vector(15 downto 0); +signal addr_i : std_logic_vector(7 downto 0); +signal last_input : std_logic; +signal input : std_logic_vector(31 downto 0); + +signal next_output : std_logic; +signal output_data : std_logic_vector (31 downto 0); + +signal bitcnt : integer range 0 to 31 := 31; + +type state_t is (IDLE, WAIT_FOR_CMD, GET_DATA, PREPARE_OUTPUT, WRITE_DATA, WAIT_FINISH); +signal state : state_t; + +signal buf_SPI_OUT : std_logic; + +begin + +spi_clk_last <= spi_clk_reg when rising_edge(CLK); +spi_clk_reg <= SPI_CLK when rising_edge(CLK); +spi_cs_reg <= SPI_CS when rising_edge(CLK); +spi_in_reg <= SPI_IN when rising_edge(CLK); + +DATA_OUT <= data_write; + +PROC_OUTPUT : process begin + wait until rising_edge(CLK); + next_output <= output_data(bitcnt); + if spi_clk_reg = '0' and spi_clk_last = '1' then + SPI_OUT <= last_input; + if operation_i = '0' and bitcnt <= 15 then + SPI_OUT <= next_output; + end if; + end if; +end process; + +PROC_INPUT_SHIFT : process begin + wait until rising_edge(CLK); + if spi_cs_reg = '1' then + bitcnt <= 31; + else + if spi_clk_reg = '1' and spi_clk_last = '0' then + if bitcnt /= 0 then + bitcnt <= bitcnt - 1; + else + bitcnt <= 31; + end if; + last_input <= spi_in_reg; + input(bitcnt) <= spi_in_reg; + end if; + end if; +end process; + +PROC_GEN_SIGNALS : process begin + wait until rising_edge(CLK); + --write_i <= (others => '0'); + READ_OUT <= '0'; + WRITE_OUT <= '0'; + case state is + when IDLE => + --operation_i <= x"0"; + if spi_cs_reg = '0' then + state <= WAIT_FOR_CMD; + end if; + + when WAIT_FOR_CMD => + if bitcnt = 22 then + operation_i <= input(23); + if (input(23) = '0') then + READ_OUT <= '1'; + else + WRITE_OUT <= '1'; + end if; + ADDR_OUT <= input(31 downto 24); + state <= GET_DATA; + end if; + + when GET_DATA => + state <= PREPARE_OUTPUT; + + when PREPARE_OUTPUT => + if READY_IN = '1' then + output_data(15 downto 0) <= DATA_IN; + end if; + state <= WRITE_DATA; + + when WRITE_DATA => + if bitcnt = 31 then + if operation_i = '1' then + WRITE_OUT <= '1'; + data_write <= input(15 downto 0); + --write_i(to_integer(unsigned(input(31 downto 28)))) <= '1'; + end if; + state <= WAIT_FINISH; + end if; + + when WAIT_FINISH => + WRITE_OUT <= '0'; + --if spi_cs_reg = '1' then + state <= IDLE; + --end if; + + end case; + + if spi_cs_reg = '1' then + state <= IDLE; + operation_i <= '0'; + end if; +end process; + +DEBUG(0) <= spi_clk_reg; +DEBUG(1) <= spi_cs_reg; +DEBUG(2) <= spi_in_reg; +DEBUG(3) <= buf_SPI_OUT; +DEBUG(7 downto 4) <= std_logic_vector(to_unsigned(bitcnt,4)); +DEBUG(14 downto 8) <= input(30 downto 24); +--DEBUG_OUT(15) <= write_i(4); + +end; \ No newline at end of file diff --git a/interface/uart_sctrl.vhd b/interface/uart_sctrl.vhd new file mode 100644 index 0000000..0b1f71b --- /dev/null +++ b/interface/uart_sctrl.vhd @@ -0,0 +1,198 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +use work.trb_net_std.all; +-- use work.version.all; +-- +-- library machxo2; +-- use machxo2.all; + + +entity uart_sctrl is + generic( + CLOCK_SPEED : integer := 33250000; + BAUD : integer := 115200 + + ); + port( + CLK : in std_logic; + RESET : in std_logic; + UART_RX : in std_logic; + UART_TX : out std_logic; + + DATA_OUT : out std_logic_vector(31 downto 0); + DATA_IN : in std_logic_vector(31 downto 0); + ADDR_OUT : out std_logic_vector(7 downto 0); + WRITE_OUT : out std_logic; + READ_OUT : out std_logic; + READY_IN : in std_logic; + + DEBUG : out std_logic_vector(15 downto 0) + ); +end entity; + + +architecture uart_sctrl_arch of uart_sctrl is + +constant CLK_DIV : integer := CLOCK_SPEED/BAUD; + +signal rx_data : std_logic_vector(7 downto 0); +signal tx_data : std_logic_vector(7 downto 0); +signal rx_ready : std_logic; +signal tx_send : std_logic; +signal tx_ready : std_logic; +signal bytecount : integer range 0 to 15; +type rx_state_t is (IDLE,START,START2,DO_COMMAND,DO_READ,SEND_BYTE1,SEND_BYTE2,SEND_BYTE3,SEND_TERM,SEND_FINISH); +signal state : rx_state_t; +signal addr_data : std_logic_vector(39 downto 0); +signal addr_data_tx : std_logic_vector(31 downto 0); + +signal timer : unsigned(25 downto 0) := (others => '0'); +signal timeout : std_logic := '0'; +signal cmd_wr : std_logic := '0'; +signal cmd_rd : std_logic := '0'; + +begin + + +THE_RX : entity work.uart_rec + port map( + CLK_DIV => CLK_DIV, + CLK => CLK, + RST => RESET, + RX => UART_RX, + DATA_OUT => rx_data, + DATA_WAITING => rx_ready + ); + +THE_TX : entity work.uart_trans + port map( + CLK_DIV => CLK_DIV, + CLK => CLK, + RST => RESET, + DATA_IN => tx_data, + SEND => tx_send, + READY => tx_ready, + TX => UART_TX + ); + +PROC_RX : process + variable tmp,tmp2 : unsigned(7 downto 0); +begin + wait until rising_edge(CLK); + READ_OUT <= '0'; + WRITE_OUT <= '0'; + tx_send <= '0'; + timer <= timer + 1; + case state is + when IDLE => + cmd_rd <= '0'; + cmd_wr <= '0'; + bytecount <= 9; + timer <= (others => '0'); + if rx_ready = '1' then + state <= START; + if rx_data = x"52" then + cmd_rd <= '1'; + elsif rx_data = x"57" then + cmd_wr <= '1'; + end if; + end if; + + when START => + if rx_ready = '1' then + if rx_data >= x"40" then + tmp2 := unsigned(rx_data) + x"09"; + else + tmp2 := unsigned(rx_data); + end if; + state <= START2; + end if; + + when START2 => + addr_data(bytecount*4+3 downto bytecount*4) <= std_logic_vector(tmp2(3 downto 0)); + if (bytecount = 0 and cmd_wr = '1') or (bytecount = 8 and cmd_rd = '1') then + state <= DO_COMMAND; + else + bytecount <= bytecount - 1; + state <= START; + end if; + + when DO_COMMAND => + WRITE_OUT <= cmd_wr; + READ_OUT <= cmd_rd; + if cmd_rd = '1' then + state <= DO_READ; + else + state <= IDLE; + end if; + +--Read cycle + when DO_READ => + if READY_IN = '1' then + addr_data_tx(31 downto 0) <= DATA_IN; + tx_send <= '1'; + tx_data <= x"52"; + state <= SEND_BYTE1; + bytecount <= 7; + end if; + + when SEND_BYTE1 => + tmp := x"0" & unsigned(addr_data_tx(bytecount*4+3 downto bytecount*4)); + state <= SEND_BYTE2; + + when SEND_BYTE2 => + if tmp(3 downto 0) > x"9" then + tmp := tmp + x"41" - x"0a"; + else + tmp := tmp + x"30"; + end if; + state <= SEND_BYTE3; + + + when SEND_BYTE3 => + + if tx_ready = '1' then + tx_data <= std_logic_vector(tmp); + tx_send <= '1'; + if bytecount = 0 then + state <= SEND_TERM; + else + bytecount <= bytecount - 1; + state <= SEND_BYTE1; + end if; + end if; + + + + when SEND_TERM=> + if tx_ready = '1' then + tx_send <= '1'; + tx_data <= x"0a"; + state <= SEND_FINISH; + end if; + when SEND_FINISH=> + if tx_ready = '1' then + tx_send <= '1'; + tx_data <= x"0d"; + state <= IDLE; + end if; + + end case; + + if RESET = '1' or timeout = '1' then + state <= IDLE; + timer <= (others => '0'); + end if; +end process; + +DATA_OUT <= addr_data(31 downto 0); +ADDR_OUT <= addr_data(39 downto 32); + +timeout <= timer(19); + + + +end architecture; \ No newline at end of file diff --git a/io/pwm.vhd b/io/pwm.vhd new file mode 100644 index 0000000..a0045bf --- /dev/null +++ b/io/pwm.vhd @@ -0,0 +1,82 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + + + +entity pwm_generator is + generic( + CHANNELS : integer := 32 + ); + port( + CLK : in std_logic; + + DATA_IN : in std_logic_vector(15 downto 0) := (others => '0'); + DATA_OUT : out std_logic_vector(15 downto 0); + WRITE_IN : in std_logic := '0'; + COMP_IN : in signed(15 downto 0); + ADDR_IN : in std_logic_vector(4 downto 0) := (others => '0'); + + + PWM : out std_logic_vector(CHANNELS-1 downto 0) + + ); +end entity; + + + +architecture pwm_arch of pwm_generator is + +type ram_t is array(0 to CHANNELS-1) of unsigned(15 downto 0); +signal set : ram_t := (others => x"87C1"); +signal set_tmp : ram_t; + +type cnt_t is array(0 to CHANNELS-1) of unsigned(16 downto 0); +signal cnt : cnt_t := (others => (others => '0')); + +signal last_flag : std_logic_vector(CHANNELS-1 downto 0) := (others => '0'); +signal flag : std_logic_vector(CHANNELS-1 downto 0) := (others => '0'); +signal pwm_i : std_logic_vector(CHANNELS-1 downto 0) := (others => '0'); + +signal i : integer range 0 to CHANNELS-1 := 0; +signal clock_enable : std_logic_vector(15 downto 0) := x"0001"; +begin + +PROC_MEM : process begin + wait until rising_edge(CLK); + if WRITE_IN = '1' then + set(to_integer(unsigned(ADDR_IN))) <= unsigned(DATA_IN); + end if; + DATA_OUT <= std_logic_vector(set(to_integer(unsigned(ADDR_IN)))); +end process; + + +GEN_REAL_VALUES : process begin + wait until rising_edge(CLK); + set_tmp(i) <= unsigned(signed(set(i)) + COMP_IN); + i <= i + 1; +end process; + +process begin + wait until rising_edge(CLK); + clock_enable <= clock_enable(14 downto 0) & clock_enable(15); +end process; + +gen_channels : for i in 0 to CHANNELS-1 generate + flag(i) <= cnt(i)(16); + + process begin + wait until rising_edge(CLK); + if clock_enable(i mod 16) = '1' then + last_flag(i) <= flag(i); + pwm_i(i) <= (last_flag(i) xor flag(i)); + cnt(i) <= cnt(i) + resize(set_tmp(i),17); + end if; + end process; +end generate; + + + +PWM(CHANNELS-1 downto 0 ) <= pwm_i(CHANNELS-1 downto 0); + +end architecture; diff --git a/machxo3/sedcheck.vhd b/machxo3/sedcheck.vhd new file mode 100644 index 0000000..b1149da --- /dev/null +++ b/machxo3/sedcheck.vhd @@ -0,0 +1,201 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +use work.trb_net_std.all; + +library ecp5um; +use ecp5um.components.all; + +entity sedcheck is + generic ( + DEV_DENSITY : string := "2100L" + ); + port( + CLK : in std_logic; + ERROR_OUT : out std_logic; + + CONTROL_IN : in std_logic_vector(3 downto 0); + DEBUG : out std_logic_vector(31 downto 0) + ); +end entity; + + +architecture sed_arch of sedcheck is + + component SEDFA + generic ( + CHECKALWAYS : string :="DISABLED"; + SED_CLK_FREQ : string :="3.5" ; + DEV_DENSITY : string :="2100L" + ); + port ( + SEDSTDBY : in std_logic; + SEDENABLE : in std_logic; + SEDSTART : in std_logic; + SEDFRCERR : in std_logic; + SEDERR : out std_logic; + SEDDONE : out std_logic; + SEDINPROG : out std_logic; + SEDCLKOUT : out std_logic + ); + end component; + + type state_t is (IDLE, INIT_1, INIT_2, INIT_3, START_1, START_2, WAITACTIVE, WAITDONE); + signal state : state_t; + signal state_bits : std_logic_vector(3 downto 0); + + signal sed_edge : std_logic; + signal sed_clock_last : std_logic; + + signal sed_clock : std_logic; + signal sed_done : std_logic; + signal sed_enable : std_logic; + signal sed_error : std_logic; + signal sed_inprogress : std_logic; + signal sed_start : std_logic; + + signal sed_clock_q : std_logic; + signal sed_done_q : std_logic; + signal sed_error_q : std_logic; + signal sed_inprogress_q : std_logic; + + signal status_i : std_logic_vector(31 downto 0); + + signal run_counter : unsigned(7 downto 0) := (others => '0'); + signal error_counter : unsigned(7 downto 0) := (others => '0'); + signal timer : unsigned(22 downto 0); + +begin + +sed_clock_last <= sed_clock_q when rising_edge(CLK); +sed_edge <= sed_clock_q and not sed_clock_last when rising_edge(CLK); + +sed_clock_q <= sed_clock when rising_edge(CLK); +sed_done_q <= sed_done when rising_edge(CLK); +sed_inprogress_q <= sed_inprogress when rising_edge(CLK); +sed_error_q <= sed_error when rising_edge(CLK); + + +--------------------------------------------------------------------------- +-- SED control state machine +--------------------------------------------------------------------------- +proc_ctrl : process begin + wait until rising_edge(CLK); + timer <= timer + 1; + case state is + when IDLE => + sed_enable <= '0'; + sed_start <= '0'; + if CONTROL_IN(0) = '1' then + state <= INIT_1; + timer <= (0 => '1', others => '0'); + end if; + when INIT_1 => + sed_enable <= '0'; + sed_start <= '0'; + if timer(5 downto 0) = 0 then + state <= INIT_2; + end if; + when INIT_2 => + sed_enable <= '1'; + sed_start <= '0'; + if timer(5 downto 0) = 0 then + state <= INIT_3; + end if; + when INIT_3 => + sed_enable <= '1'; + sed_start <= '0'; + if timer(5 downto 0) = 0 then + state <= START_1; + end if; + when START_1 => + sed_enable <= '1'; + sed_start <= '0'; + if sed_edge = '1' then + state <= START_2; + end if; + when START_2 => + sed_enable <= '1'; + sed_start <= '1'; + if sed_edge = '1' and sed_inprogress_q = '1' then + state <= WAITACTIVE; + end if; + when WAITACTIVE => + sed_enable <= '1'; + sed_start <= '1'; + if sed_edge = '1' and sed_done_q = '0' then + state <= WAITDONE; + end if; + when WAITDONE => + sed_enable <= '1'; + sed_start <= '1'; + if (sed_edge = '1' and sed_inprogress_q = '0' and sed_done_q = '1') then + state <= INIT_1; + timer <= (0 => '1', others => '0'); + run_counter <= run_counter + 1; + if sed_error_q = '1' then + error_counter <= error_counter + 1; + end if; + end if; + end case; + + if CONTROL_IN(0) = '0' or (timer = 0 and state /= IDLE) then + sed_enable <= '0'; + state <= IDLE; + end if; + +end process; + +--------------------------------------------------------------------------- +-- Status Information +--------------------------------------------------------------------------- +state_bits <= x"8" when state = IDLE else + x"1" when state = INIT_1 else + x"2" when state = INIT_2 else + x"3" when state = INIT_3 else + x"4" when state = START_1 else + x"5" when state = START_2 else + x"6" when state = WAITACTIVE else + x"7" when state = WAITDONE else +-- x"9" when state = RESULT else + x"F"; + +status_i(3 downto 0) <= state_bits; +status_i(4) <= sed_clock_q; +status_i(5) <= sed_enable; +status_i(6) <= sed_start; +status_i(7) <= sed_done_q; +status_i(8) <= sed_inprogress_q; +status_i(9) <= sed_error_q; +status_i(10) <= not sed_edge; +status_i(15 downto 11) <= (others => '0'); +status_i(23 downto 16) <= std_logic_vector(run_counter)(7 downto 0); +status_i(31 downto 24) <= std_logic_vector(error_counter)(7 downto 0); + +ERROR_OUT <= sed_error; +DEBUG <= status_i when rising_edge(CLK); + +--------------------------------------------------------------------------- +-- SED +--------------------------------------------------------------------------- +THE_SED : SEDFA + generic map( + CHECKALWAYS => "DISABLED", + SED_CLK_FREQ => "3.5", + DEV_DENSITY => DEV_DENSITY + ) + port map( + SEDSTDBY => '0', + SEDENABLE => sed_enable, + SEDSTART => sed_start, + SEDFRCERR => '0', + SEDERR => sed_error, + SEDDONE => sed_done, + SEDINPROG => sed_inprogress, + SEDCLKOUT => sed_clock + ); + + +end architecture; -- 2.43.0