~ruther/vhdl-spi-2

19cab4548832988e5a3dd440796c69617c46e2f6 — Rutherther 3 months ago 5c7a8bb
fix: support other divisors than 2
3 files changed, 36 insertions(+), 16 deletions(-)

M hdl_spi/src/spi_master.vhd
M hdl_spi/src/spi_master_ctrl.vhd
M hdl_spi/src/spi_masterslave.vhd
M hdl_spi/src/spi_master.vhd => hdl_spi/src/spi_master.vhd +3 -0
@@ 84,12 84,15 @@ begin  -- architecture a1
    generic map (
      SIZES            => SIZES,
      SIZES_2LOG       => SIZES_2LOG,
      DIVISORS         => DIVISORS,
      DIVISORS_LOG2    => DIVISORS_LOG2,
      CSN_PULSE_CYCLES => CSN_PULSE_CYCLES)
    port map (
      clk_i                => clk_i,
      rst_in               => rst_in,
      en_i                 => en_i,
      size_sel_i           => size_sel_i,
      div_sel_i            => div_sel_i,
      pulse_csn_i          => pulse_csn_i,
      clock_rising_i       => clock_rising,
      rx_block_on_full_i   => rx_block_on_full_i,

M hdl_spi/src/spi_master_ctrl.vhd => hdl_spi/src/spi_master_ctrl.vhd +16 -2
@@ 8,6 8,8 @@ entity spi_master_ctrl is
  generic (
    SIZES            : natural_vector := (8, 16);
    SIZES_2LOG       : natural := 1;
    DIVISORS         : natural_vector := (2, 4, 6, 8, 16, 32, 64, 128, 256);
    DIVISORS_LOG2    : natural := 3;
    CSN_PULSE_CYCLES : natural := 1
  );



@@ 16,6 18,7 @@ entity spi_master_ctrl is
    rst_in               : in  std_logic;
    en_i                 : in  std_logic;
    size_sel_i           : in  std_logic_vector(SIZES_2LOG - 1 downto 0);
    div_sel_i            : in  std_logic_vector(DIVISORS_LOG2 - 1 downto 0);
    pulse_csn_i          : in  std_logic;
    clock_rising_i       : in  std_logic;
    rx_block_on_full_i   : in  std_logic;


@@ 43,6 46,7 @@ end entity spi_master_ctrl;

architecture a1 of spi_master_ctrl is
  constant MAX_SIZE : natural := get_max_natural(SIZES);
  constant MAX_DIVISOR : natural := get_max_natural(DIVISORS);

  type states_t is (RESET, IDLE, SHIFTING, NEXT_DATA, CSN_PULSE, CSN_RISING);



@@ 71,6 75,7 @@ architecture a1 of spi_master_ctrl is
  signal transmission_done : std_logic;

  signal shifting_length : integer range 0 to MAX_SIZE;
  signal selected_divisor : integer range 0 to MAX_DIVISOR;
  signal clear_lost_rx_data : std_logic;
begin  -- architecture a1
  registers: process (clk_i) is


@@ 153,11 158,19 @@ begin  -- architecture a1
        end if;
      when NEXT_DATA =>
        csn_o <= '0';
        sck_mask_o <= '0';
        if selected_divisor = 2 then
          sck_mask_o <= '0';
        else
          sck_mask_o <= '1';
        end if;

        if tx_got_data = '1' then
          sck_mask_o <= '1';
          switch_to(SHIFTING, shifting_length - 1);
          if selected_divisor = 2 then
            switch_to(SHIFTING, shifting_length - 1);
          else
            switch_to(SHIFTING, shifting_length);
          end if;
          ack_tx_got_data <= '1';
        else
          switch_to(IDLE, 0);


@@ 281,6 294,7 @@ begin  -- architecture a1
  -- Internal
  clear_lost_rx_data <= '1' when clear_lost_rx_data_i = '1' or curr_state = RESET else '0';
  shifting_length <= SIZES(to_integer(unsigned(size_sel_i)));
  selected_divisor <= DIVISORS(to_integer(unsigned(div_sel_i)));

  -- Enable Outputs
  miso_en_o <= '0';

M hdl_spi/src/spi_masterslave.vhd => hdl_spi/src/spi_masterslave.vhd +17 -14
@@ 113,6 113,8 @@ begin  -- architecture a1

  master_ctrl : entity work.spi_master_ctrl
    generic map (
      DIVISORS         => DIVISORS,
      DIVISORS_LOG2    => DIVISORS_LOG2,
      SIZES            => SIZES,
      SIZES_2LOG       => SIZES_2LOG,
      CSN_PULSE_CYCLES => CSN_PULSE_CYCLES)


@@ 121,6 123,7 @@ begin  -- architecture a1
      rst_in               => rst_in,
      en_i                 => master_en,
      size_sel_i           => size_sel_i,
      div_sel_i            => div_sel_i,
      pulse_csn_i          => pulse_csn_i,
      rx_block_on_full_i   => rx_block_on_full_i,
      rx_en_i              => rx_en_i,


@@ 129,20 132,20 @@ begin  -- architecture a1
      tx_valid_i           => tx_valid_i,
      clear_lost_rx_data_i => clear_lost_rx_data_i,

      clock_rising_i       => master_clock_rising,
      rx_valid_o           => master_rx_valid,
      tx_ready_o           => master_tx_ready,
      busy_o               => master_busy,
      err_lost_rx_data_o   => master_err_lost_rx_data,
      rst_on               => master_ctrl_rst_n,
      csn_o                => master_csn,
      csn_en_o             => master_csn_en,
      mosi_en_o            => master_mosi_en,
      miso_en_o            => master_miso_en,
      sck_mask_o           => master_sck_mask,
      sck_en_o             => master_sck_en,
      gen_clk_en_o         => master_start_clock,
      latch_tx_data_o      => master_latch_new_tx_data);
      clock_rising_i     => master_clock_rising,
      rx_valid_o         => master_rx_valid,
      tx_ready_o         => master_tx_ready,
      busy_o             => master_busy,
      err_lost_rx_data_o => master_err_lost_rx_data,
      rst_on             => master_ctrl_rst_n,
      csn_o              => master_csn,
      csn_en_o           => master_csn_en,
      mosi_en_o          => master_mosi_en,
      miso_en_o          => master_miso_en,
      sck_mask_o         => master_sck_mask,
      sck_en_o           => master_sck_en,
      gen_clk_en_o       => master_start_clock,
      latch_tx_data_o    => master_latch_new_tx_data);

  slave_ctrl : entity work.spi_slave_ctrl
    generic map (

Do not follow this link