OpenCores
URL https://opencores.org/ocsvn/spi_slave/spi_slave/trunk

Subversion Repositories spi_slave

[/] [spi_slave/] [trunk/] [pcore/] [opb_spi_slave_v1_00_a/] [hdl/] [vhdl/] [shift_register.vhd] - Blame information for rev 35

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dkoethe
-------------------------------------------------------------------------------
2
--* 
3
--* @short Shift-Register
4
--* 
5
--* Control Register Description:
6
--* @li Bit0: DGE  :  Global Device Enable
7
--* @li Bit1: TX_EN:  Transmit enable
8
--* @li Bit2: RX_EN:  Receive enable
9
--*
10
--* Generics described in top entity.
11
--* @port opb_ctl_reg Control Register
12
--*
13
--* @see opb_spi_slave
14
--*    @author: Daniel Köthe
15
--*   @version: 1.1
16
--* @date: 2007-11-11
17
--/
18
-- Version 1.0 Initial Release
19
-- Version 1.1 rx_cnt/tx_cnt only increment if < C_SR_WIDTH
20 19 dkoethe
-- Version 1.2 removed delays for simulation
21 2 dkoethe
-------------------------------------------------------------------------------
22
 
23
library ieee;
24
use ieee.std_logic_1164.all;
25
use IEEE.STD_LOGIC_ARITH.all;
26
 
27
library work;
28
use work.opb_spi_slave_pack.all;
29
 
30
entity shift_register is
31
 
32
  generic (
33
    C_SR_WIDTH  : integer              := 8;
34
    C_MSB_FIRST : boolean              := true;
35
    C_CPOL      : integer range 0 to 1 := 0;
36
    C_PHA       : integer range 0 to 1 := 0);
37
 
38
  port (
39
    rst         : in  std_logic;
40
    -- control register
41
    opb_ctl_reg : in  std_logic_vector(C_OPB_CTL_REG_WIDTH-1 downto 0);
42
    -- external 
43
    sclk        : in  std_logic;
44
    ss_n        : in  std_logic;
45
    mosi        : in  std_logic;
46
    miso_o      : out std_logic;
47
    miso_i      : in  std_logic;
48
    miso_t      : out std_logic;
49
    -- transmit fifo
50
    sr_tx_clk   : out std_logic;
51
    sr_tx_en    : out std_logic;
52
    sr_tx_data  : in  std_logic_vector(C_SR_WIDTH-1 downto 0);
53
    -- receive fifo
54
    sr_rx_clk   : out std_logic;
55
    sr_rx_en    : out std_logic;
56
    sr_rx_data  : out std_logic_vector(C_SR_WIDTH-1 downto 0));
57
end shift_register;
58
 
59
 
60
architecture behavior of shift_register is
61
  --* Global
62
  signal sclk_int     : std_logic;
63
  signal sclk_int_inv : std_logic;
64
  signal rx_cnt       : integer range 0 to 31 := 0;
65
 
66
  -- RX
67
  signal rx_sr_reg      : std_logic_vector(C_SR_WIDTH-2 downto 0);
68
  signal sr_rx_en_int   : std_logic;
69
  signal sr_rx_data_int : std_logic_vector(C_SR_WIDTH-1 downto 0);
70
 
71
  -- tx
72
  signal miso_int       : std_logic;
73
  signal tx_cnt         : integer range 0 to 31 := 0;
74
  signal sr_tx_en_int   : std_logic;
75
  signal sr_tx_data_int : std_logic_vector(C_SR_WIDTH-1 downto 0);
76
 
77
 
78
begin  -- behavior
79
 
80
  miso_t <= ss_n;                       -- tristate
81
 
82
 
83
  sclk_int <= sclk when (C_PHA = 0 and C_CPOL = 0) else
84
              sclk when (C_PHA = 1 and C_CPOL = 1) else
85
              not sclk;
86
 
87
 
88 19 dkoethe
  sr_rx_en <= sr_rx_en_int;
89
  sr_tx_en <= sr_tx_en_int;
90 2 dkoethe
 
91
  --* reorder received bits if not "MSB_First"
92
  reorder_rx_bits : process(sr_rx_data_int)
93
  begin
94
    for i in 0 to C_SR_WIDTH-1 loop
95
      if C_MSB_FIRST then
96 19 dkoethe
        sr_rx_data(i) <= sr_rx_data_int(i);
97 2 dkoethe
      else
98 19 dkoethe
        sr_rx_data(C_SR_WIDTH-1-i) <= sr_rx_data_int(i);
99 2 dkoethe
      end if;
100
    end loop;  -- i
101
  end process reorder_rx_bits;
102
 
103
  --* reorder transmit bits if not "MSB_First" 
104
  reorder_tx_bits : process(sr_tx_data)
105
  begin
106
    for i in 0 to C_SR_WIDTH-1 loop
107
      if C_MSB_FIRST then
108
        sr_tx_data_int(i) <= sr_tx_data(i);
109
      else
110
        sr_tx_data_int(C_SR_WIDTH-1-i) <= sr_tx_data(i);
111
      end if;
112
    end loop;  -- i
113
  end process reorder_tx_bits;
114
 
115
 
116
  -----------------------------------------------------------------------------
117
 
118
  sr_rx_clk <= sclk_int;
119
 
120
  sr_rx_data_int <= rx_sr_reg & mosi;
121
 
122
  --* RX-Shift-Register
123
  rx_shift_proc : process(rst, opb_ctl_reg, sclk_int)
124
  begin
125
    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
126
      rx_cnt       <= 0;
127
      sr_rx_en_int <= '0';
128
      rx_sr_reg    <= (others => '0');
129
 
130
    elsif rising_edge(sclk_int) then
131
      if (ss_n = '0') then
132
        rx_sr_reg <= rx_sr_reg(C_SR_WIDTH-3 downto 0) & mosi;
133
        if (rx_cnt = C_SR_WIDTH-2) then
134
          rx_cnt       <= rx_cnt +1;
135
          sr_rx_en_int <= '1';
136
          elsif (rx_cnt = C_SR_WIDTH-1) then
137
            rx_cnt       <= 0;
138
            sr_rx_en_int <= '0';
139
          else
140
            rx_cnt <= rx_cnt +1;
141
          end if;
142
        else
143
          -- ss_n high
144
          -- assert framing error if cnt != 0?
145
          sr_rx_en_int <= '0';
146
          rx_cnt       <= 0;
147
        end if;
148
      end if;
149
    end process rx_shift_proc;
150
 
151
-------------------------------------------------------------------------------
152
      -- TX Shift Register
153
      sr_tx_clk    <= sclk_int_inv;
154
      sclk_int_inv <= not sclk_int;
155
 
156
      miso_o <= sr_tx_data_int(C_SR_WIDTH-1) when (tx_cnt = 0) else
157
                miso_int;
158
 
159
 
160
      --* TX Shift-Register
161
      tx_shift_proc : process(rst, opb_ctl_reg, sclk_int_inv)
162
      begin
163
        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
164
          tx_cnt       <= 0;
165
          sr_tx_en_int <= '0';
166
          miso_int     <= '0';
167
        elsif rising_edge(sclk_int_inv) then
168
          if (ss_n = '0') then
169
            if (tx_cnt /= C_SR_WIDTH-1) then
170
              miso_int <= sr_tx_data_int(C_SR_WIDTH-1-(tx_cnt+1));
171
            end if;
172
            if (tx_cnt = C_SR_WIDTH-2) then
173
              sr_tx_en_int <= '1';
174
              tx_cnt       <= tx_cnt +1;
175
              elsif (tx_cnt = C_SR_WIDTH-1) then
176
                tx_cnt       <= 0;
177
                sr_tx_en_int <= '0';
178
              else
179
                tx_cnt <= tx_cnt +1;
180
              end if;
181
            else
182
              -- ss_n high
183
              -- assert framing error if cnt != 0?
184
              sr_tx_en_int <= '0';
185
              tx_cnt       <= 0;
186
            end if;
187
          end if;
188
        end process tx_shift_proc;
189
-------------------------------------------------------------------------------
190
 
191
        end behavior;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.