zoukankan      html  css  js  c++  java
  • VSPI core implements an SPI interface

      1 ------------------------------------------------------------------------ 
      2 -- Copyright 1997-1998 VAutomation Inc. Nashua NH USA.  
      3 -- Visit HTTP://www.vautomation.com for mor details on our other 
      4 -- Synthesizable microprocessor and peripheral cores. 
      5 -- 
      6 -- This program is free software; you can redistribute it and/or modify 
      7 -- it under the terms of the GNU General Public License version 2 as 
      8 -- published by the Free Software Foundation. 
      9 -- 
     10 -- This program is distributed in the hope that it will be useful, 
     11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of 
     12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     13 -- GNU General Public License for more details. 
     14 -- 
     15 -- The GNU Public License can be found at HTTP://www.gnu.org. 
     16 --  
     17 -- The copyright notice above MUST remain in the source code at all 
     18 -- times! 
     19 -- 
     20 -- File: vspi.vhd 
     21 -- Revision: $Name: REV9910 $ 
     22 -- Gate Count: 500 gates (LSI Logic 10K) 
     23 -- Description: 
     24 -- 
     25 --      Serial Peripheral Interface (SPI) 
     26 -- 
     27 -- The VSPI core implements an SPI interface compatible with the many 
     28 -- serial EEPROMs, and microcontrollers. The VSPI core is typically used 
     29 -- as an SPI master, but it can be configured as an SPI slave as well. 
     30 -- 
     31 -- The SPI bus is a 3 wire bus that in effect links a serial shift 
     32 -- register between the "master" and the "slave". Typically both the 
     33 -- master and slave have an 8 bit shift register so the combined 
     34 -- register is 16 bits. When an SPI transfer takes place, the master and 
     35 -- slave shift their shift registers 8 bits and thus exchange their 8 
     36 -- bit register values. 
     37 -- 
     38 -- The VPSI core is completely software configurable. The clock 
     39 -- polarity, clock phase, the clock frequency in master mode, and the 
     40 -- number of bits to be transferred are all software programmable. These 
     41 -- configuration bits are usually determined by the capabilities of the 
     42 -- other device you wish to communicate with. 
     43 -- 
     44 -- SPI supports multiple slaves on a single 3 wire bus by using seperate 
     45 -- SLaVe SELect signals (SVLSEL) to enable the desired slave. Multiple 
     46 -- masters are also supported and some support is provided for detecting 
     47 -- collisions when multiple masters attempt to transfer at the same 
     48 -- time. 
     49 -- 
     50 -- A Wired-OR mode is provided which allows multiple masters to collide 
     51 -- on the bus without risk of damage. In this mode, an external pullup 
     52 -- resisitor is required on the SI and SO pins. WOR mode also allows the 
     53 -- SPI bus to operate as a 2 wire bus by connecting the SI and SO pins 
     54 -- together to form a single bidirectional data pin. 
     55 -- 
     56 -- Generally, pullups are recommended on all of the external SPI signals 
     57 -- to insure they are held in a valid state even when the VSPI core is 
     58 -- disabled. 
     59 -- 
     60 -- Limitations: 
     61 
     62 --      When operating as a slave, the SPI clock signal (SCK) must be 
     63 --      slower than 1/8th of the CPU clock. 1/16th is recommended. Note 
     64 --      that this core is fully synchronous to the cpu CLK and thus SCK 
     65 --      is sampled and then operated on. This results in 3 to 4 clocks 
     66 --      of delay which will violate the SPI spec if SCK is faster than 
     67 --      1/8th of the CPU clock. When the VSPI core is in master mode, it 
     68 --      operates exactly on the proper edges since it is generating SCK. 
     69 -- 
     70 --      The VSPI core was specifically designed to be an SPI master and 
     71 --      to be connected to a microprocessor such as VAutomations 
     72 --      V8-uRISC CPU. This core also has the capability to be a slave 
     73 --      but that feature is considered secondary which is why it is 
     74 --      speed limited. 
     75 -- 
     76 -- Register Definition: 
     77 -- Addr Name    R/W     Description 
     78 --  0   DOUT    W       8 Bit data out register 
     79 --  0   DIN     R       8 Bit data in register 
     80 --  1   CTL     R/W     Control Register 
     81 --                      [0]=Reserved. 
     82 --                      [1]=MSTENB      Enable SPI master mode 
     83 --                      [2]=WOR Wire-OR mode enabled 
     84 --                      [3]=CKPOL       Clock Polarity 1=SCK idles high, 
     85 --                                      0=SCK idles low 
     86 --                      [4]=PHASE       Phase Select 
     87 --                      [6:5]=DVD       Clock divide - 00=8, 01=16, 
     88 --                                      10=32, 11=64 
     89 --                      [7]=IRQENB      Interrupt enable 
     90 --  2   STATUS  R/W     Interrupt Status register 
     91 --                      Each bit of the status register is cleared to 
     92 --                      zero by by writting ONE to the respective bit. 
     93 --                      [7]=IRQ Interrupt active 
     94 --                              Set at the end of a master mode 
     95 --                              transfer, or when SLVSEL goes high on a 
     96 --                              slave transfer 
     97 --                      [6]=Overrun 
     98 --                              This bit is set when the DOUT register 
     99 --                              is written while an SPI transfer is in 
    100 --                              progress. 
    101 --                      [5]=COL 
    102 --                              This bit is set when there is a master 
    103 --                              mode collision between multiple SPI 
    104 --                              masters. It is set when SLVSEL goes low 
    105 --                              while MSTENB=1. 
    106 --                      [2:4]=zero 
    107 --                      [1]=TXRUN 
    108 --                              1=Master mode operation underway. 
    109 --                              This bit is read only. 
    110 --                      [0]=SLVSEL 
    111 --                              This bit corresponds to the SLVSEL pin 
    112 --                              on the VSPI core (note that this is 
    113 --                              normally interted at the IO pin). read 
    114 --                              only. 
    115 --  3   SSEL    R/W     Slave Select/bit count register 
    116 --                      SSEL[7:5] 
    117 --                              Number of bits to shift in master mode,  
    118 --                              000=8 bits, 001=1 bit, 111=7 bits. 
    119 --                      SSEL[4:0] 
    120 --                              5 individual Slave Selects for master 
    121 --                              mode 
    122 -- 
    123 -- The VSPI core operates in two fundamentally different modes based on 
    124 -- the PHASE bit (CTL[4]). The two modes are depicted in the timing 
    125 -- diagrams below. The key difference centers around the fact that SPI 
    126 -- data is clocked out on one edge of the clock, and sampled on the 
    127 -- other. The two modes select where the opposite edge DFF is placed. 
    128 -- When PHASE=0, a negative edge flop is inserted into the shift_in 
    129 -- path. The shift_out data is tricky because we must output data from 
    130 -- the TX_HOLD register for the first bit as we have not seen a clock on 
    131 -- SCK to clock the data into the shift register. When PHASE=1, the 
    132 -- negative edge flop is inserted into the shift_out path to hold the 
    133 -- data for an extra 1/2 clock. 
    134 -- 
    135 -- Microprocessor interface 
    136 --      The VSPI microprocessor interface is quite simple and connects 
    137 -- easily to VAutomations V8-uRISC CPU. Transfers are fully synchronous 
    138 -- to the CLK signal. When CHIP_SEL and WRITE are both active at the 
    139 -- rising edge of CLK, a write to the desired register occurs. CHIP_SEL 
    140 -- and WRITE should only be active for 1 clock cycle. 
    141 -- 
    142 -- Timing diagram: 
    143 -- 
    144 -- PHASE=0 (POLCK=0 shown, invert SCKI if POLCK=1) 
    145 -- Cycle #     | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 
    146 --                _   _   _   _   _   _   _   _       
    147 -- SCK    _______| |_| |_| |_| |_| |_| |_| |_| |_____ 
    148 --              ___ ___ ___ ___ ___ ___ ___ ___ 
    149 -- MOSI  ------<_7_X_6_X_5_X_4_X_3_X_2_X_1_X_0_>----- 
    150 --            _____ ___ ___ ___ ___ ___ ___ _______ 
    151 -- MISO  ----<___7_X_6_X_5_X_4_X_3_X_2_X_1_X_0_XXXX>- 
    152 --            _____________________________________ 
    153 -- SLVSEL ___/                                     \_ 
    154 -- Shift register runs on the second edge of SCKI. A negative edge flop 
    155 -- is placed in the shift_in path to sample data on the first edge of 
    156 -- SCKI. 
    157 
    158 -- PHASE=1 (POLCK=0 shown, invert SCKI if POLCK=1) 
    159 -- Cycle #       | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 
    160 --                _   _   _   _   _   _   _   _       
    161 -- SCK   ________| |_| |_| |_| |_| |_| |_| |_| |_______ 
    162 --                ___ ___ ___ ___ ___ ___ ___ ___ 
    163 -- MOSI  --------<_7_X_6_X_5_X_4_X_3_X_2_X_1_X_0_>----- 
    164 --                _ ___ ___ ___ ___ ___ ___ _________ 
    165 -- MISO  ----XXXXX_7_X_6_X_5_X_4_X_3_X_2_X_1_X_0_____>- 
    166 --            _______________________________________ 
    167 -- SLVSEL ___/                                       \_ 
    168 -- Shift register runs on the second edge of SCKI. A negative edge flop 
    169 -- is placed in the shift_out path to hold data data for an extra 1/2 
    170 -- clock. 
    171 -- 
    172 -- Crude block diagram: 
    173 -- 
    174 -- DATAIN--------------------------+ 
    175 --                                 | 
    176 --                    |\           | 
    177 -- MISO-------+-------> \      +---v--------+                |\ 
    178 --            |       |  >-----> 8bit Shift >-------+--------> \ 
    179 --            |    +--> /      |> Register  |       |        |  >-->MOSI 
    180 --            |    |  |/       +---v--------+       |   +----> /         
    181 --            |    |               |                |   |    |/ 
    182 --            |    |               +---DATAOUT      |   |       
    183 --            |    |                                |   |       
    184 --            |    +-------------------------+      |   |                
    185 --            |     +------------------------|------+   | 
    186 --            |     |  |\                    |          |  
    187 --            |     +--> \        +----+     |          |  
    188 --            |        |  >------->Neg >-----+----------+  
    189 --            +--------> /        |DFF |                   
    190 --                     |/        O|>   |                   
    191 --                                +----+                   
    192 -- Not shown are the control and status registers, the master mode bit 
    193 -- counters and other control logic. 
    194 --  
    195 -- IO cell Requirements: 
    196 -- The IO cells required for the SPI bus are quite simple. The following 
    197 -- VHDL code will synthesize to the appropriate cells. 
    198 -- 
    199 --   miso = misoo when misoe='1' ELSE 'Z';  -- tristate buffer 
    200 --   mosi = mosio when mosie='1' ELSE 'Z';  -- tristate buffer 
    201 --   sck  = scko  when scke ='1' ELSE 'Z';  -- tristate buffer 
    202 
    203 ----------------------------------------------------------------------- 
    204 -- This product is licensed to: 
    205 -- $name$ of $company$ 
    206 -- for use at site(s): 
    207 -- $site$ 
    208 --------------Revision History----------------------------------------- 
    209 -- $Log: vspi.vhd,v $ 
    210 -- Revision 1.7  1999/09/09 16:02:37  scott 
    211 -- std_ulogic'ified, numeric_std'ified, RMM'ified 
    212 -- 
    213 -- Revision 1.6  1999/02/17 00:51:50  eric 
    214 -- Added more checking on various error conditions. 
    215 -- 
    216 -- Revision 1.5  1999/02/02 19:56:13  eric 
    217 -- Changes to fully sync to the CPU clock. 
    218 -- 
    219 -- Revision 1.4  1998/10/16 13:54:57  eric 
    220 -- Corrected missing sensitiviy list signals for FIRST_BIT. 
    221 -- 
    222 -- Revision 1.3  1998/09/30 14:56:56  eric 
    223 -- Initial release level. 
    224 -- 
    225 -- Revision 1.2  1998/09/24 02:51:44  eric 
    226 -- Master mode works in phase=0. 
    227 ----------------------------------------------------------------------- 
    228 -- 
    229 library ieee;
    230 use ieee.std_logic_1164.all; -- we use IEEE standard 1164 logic types.
    231 --use ieee.numeric_std.all;    -- + and - operators 
    232 
    233 --use ieee.std_logic_1164.all; 
    234 use ieee.std_logic_arith.all;
    235 use ieee.std_logic_signed.all;
    236 use ieee.std_logic_unsigned.all;
    237 use ieee.std_ulogic_vector.all;
    238 
    239 entity vspi is  ----------------------------ENTITY---------------------
    240   port(
    241     clk      : in  std_ulogic;   -- everything clocks on rising edge
    242     rst      : in  std_ulogic;   -- reset
    243     addr     : in  std_ulogic_vector(1 downto 0);  -- address bus
    244     datain   : in  std_ulogic_vector(7 downto 0);  -- data bus
    245     dataout  : out std_ulogic_vector(7 downto 0);  -- data bus
    246     write    : in  std_ulogic;   -- write enable
    247     chip_sel : in  std_ulogic;   -- device Select
    248     irq      : out std_ulogic;   -- interrupt request
    249     -- SPI interface without IO cells 
    250     misoe : out std_ulogic;   -- MISO tristate enable
    251     misoi : in  std_ulogic;   -- Master in/Slave out data in
    252     misoo : out std_ulogic;   -- MISO data out
    253     mosie : out std_ulogic;   -- MOSI tristate enable
    254     mosii : in  std_ulogic;   -- Master out/Slave in data in
    255     mosio : out std_ulogic;   -- MOSI data out
    256     scke  : out std_ulogic;   -- SCK Clock tristate enable
    257     scki  : in  std_ulogic;
    258     -- SCK Clock input (shift register runs on this) 
    259     scko    : out std_ulogic;   -- SCK clock output
    260     slvsele : out std_ulogic;   -- tristate enable for slave selects
    261     slvselo : out std_ulogic_vector(4 downto 0);
    262     -- external slave selects 
    263     slvsel : in  std_ulogic    -- Slave Select
    264   );
    265 end vspi;
    266 
    267 architecture empty of vspi is -------- ARCHITECTURE empty --------
    268 
    269   -- This architecture is provided to easily and quickly remove the SPI 
    270   -- core for your ASIC or FPGA. 
    271 
    272 begin
    273   dataout = (others => '0');
    274   irq     = '0';
    275   misoo   = '0';
    276   misoe   = '0';
    277   mosie   = '0';
    278   mosio   = '0';
    279   scko    = '0';
    280   scke    = '0';
    281   slvsele = '0';
    282   slvselo = "00000";
    283 end empty;
    284 
    285 architecture rtl of vspi is -----------ARCHITECTURE rtl-----------
    286   attribute sync_set_reset        : string; -- required for synopsys
    287   attribute sync_set_reset of rst : signal is "true";
    288   -- required for synopsys 
    289 
    290   signal bit_ctr : std_ulogic_vector(2 downto 0);
    291   -- # bits in a byte 
    292   signal ctl_reg : std_ulogic_vector(7 downto 0);
    293   -- control register 
    294   signal col_flag : std_ulogic; -- collision flag
    295   signal dvd_ctr  : std_ulogic_vector(4 downto 0); -- clock divider
    296   signal dvd2     : std_ulogic;
    297   signal dvd_zero : std_ulogic; -- clk divider controls
    298   signal irq_flag : std_ulogic;
    299   -- local version of IRQ before gated with IRQENB 
    300   signal master_mode : std_ulogic; -- Master mode when 1
    301   signal misoe_lcl   : std_ulogic; -- local version
    302   signal mosie_lcl   : std_ulogic; -- local version
    303   signal oflow       : std_ulogic;
    304   signal open_drain  : std_ulogic;
    305   signal phase       : std_ulogic;
    306   signal polck       : std_ulogic;
    307   signal sck_r1      : std_ulogic;
    308   signal sck_r2      : std_ulogic;
    309   signal sck_r3      : std_ulogic; -- synchronizers
    310   signal sel_clk     : std_ulogic_vector(1 downto 0);
    311   signal shift_reg   : std_ulogic_vector(7 downto 0);
    312   -- THE SPI shift register  
    313   signal shift_clk               : std_ulogic;
    314   signal shift_clk_negedge       : std_ulogic; -- negative edge of SCK
    315   signal shift_negative_edge_nxt : std_ulogic;
    316   signal shift_negative_edge     : std_ulogic;
    317   signal shift_datain            : std_ulogic;
    318   signal shift_dataout           : std_ulogic;
    319   signal slvsel_r1               : std_ulogic;
    320   signal slvsel_r2               : std_ulogic;
    321   signal slvsel_r3               : std_ulogic; -- synchronizers
    322   signal spi_go                  : std_ulogic; -- begin a transfer
    323   signal ssel                    : std_ulogic_vector(7 downto 0);
    324   -- slave select register 
    325   signal status : std_ulogic_vector(7 downto 0);
    326   -- status register 
    327   signal tx_end : std_ulogic;
    328   -- TX has completed, TX_RUN will go low 
    329   signal tx_run      : std_ulogic; -- tx is running
    330   signal tx_start    : std_ulogic;
    331   signal tx_start_r1 : std_ulogic;
    332 
    333 begin   ---------------------------------------------------------------
    334 
    335   mosio = shift_dataout when mosie_lcl = '1' and open_drain = '0' else
    336            '0';  
    337   mosie = mosie_lcl when open_drain = '0' else 
    338            '1' when mosie_lcl = '1' and shift_dataout = '0' else 
    339            -- drive low when open drain enabled. 
    340   '0';
    341 
    342   misoo = shift_dataout when misoe_lcl = '1' and open_drain = '0' else
    343            '0';  
    344   misoe = misoe_lcl when open_drain = '0' else 
    345            '1' when misoe_lcl = '1' and shift_dataout = '0' else 
    346            -- drive low when open drain enabled. 
    347   '0';
    348 
    349   misoe_lcl = '1' when master_mode = '0' and slvsel = '1' else
    350                '0'; 
    351   mosie_lcl = '1' when master_mode = '1' else 
    352                '0'; 
    353 
    354   -- spi_go initiates a transfer - A write to the DOUT reg in master 
    355   -- mode ignore the CPU write if we're already running. 
    356   spi_go = '1' when chip_sel = '1' and write = '1' and addr = "00" and
    357                      tx_run = '0' and slvsel_r3 = '0' else 
    358             '0'; 
    359 
    360   sr_proc : process(clk) -------------Shift register----------------
    361   begin
    362     if (clk'event and clk = '1') then
    363       if (rst = '1') then
    364         shift_reg = "00000000";   -- sync reset
    365       else
    366         if (spi_go = '1') then -- don't reload while running
    367           shift_reg  = datain;    -- load with data from CPU
    368         elsif (shift_clk = '1') then
    369           shift_reg = shift_reg(6 downto 0) & shift_datain;
    370         end if;
    371       end if;
    372     end if;
    373   end process;
    374 
    375   neg_proc : process(clk) ----------Hold time register--------------
    376   begin
    377     if (clk'event and clk = '1') then        -- negative edge pipeline DFF
    378       if (rst = '1') then
    379         shift_negative_edge = '0';     -- sync reset
    380       elsif (shift_clk_negedge = '1') then
    381         shift_negative_edge  = shift_negative_edge_nxt;
    382       elsif (spi_go = '1') then
    383         shift_negative_edge  = datain(7); -- preload for phase=0 mode
    384       end if;
    385     end if;
    386   end process;
    387 
    388   shift_negative_edge_nxt = shift_reg(7) when phase = '1' else
    389                              misoi when master_mode = '1' else 
    390                              mosii; 
    391 
    392   shift_dataout = shift_negative_edge when phase = '1' else
    393                    -- add in the negative edge dff on phase=1 
    394   shift_reg(7);
    395 
    396   shift_datain = shift_negative_edge when phase = '0' else
    397                   -- insert the neg DFF in phase=0 
    398   misoi when master_mode = '1' else
    399                   mosii; 
    400 
    401   tr_proc : process(clk) ---------------TX run------------------
    402   -- this bit is active while a transmit is running 
    403   begin
    404     if (clk'event and clk = '1') then
    405       if (rst = '1') then
    406         tx_run = '0';     -- sync reset
    407       else
    408         if (tx_start = '1') then
    409           tx_run  = '1';
    410         elsif (tx_end = '1') then
    411           tx_run = '0';
    412         end if;
    413       end if;
    414     end if;
    415   end process;
    416 
    417   bc_proc : process (clk)
    418   begin -------------Bit counter for master mode----------------
    419     if (clk'event and clk = '1') then
    420       if (rst = '1') then -- sync reset
    421         bit_ctr = "000";
    422       else
    423         if (tx_start = '1') then
    424           bit_ctr = ssel(7 downto 5);
    425         elsif (shift_clk = '1') then
    426           bit_ctr = std_ulogic_vector(unsigned(bit_ctr)-1);
    427         end if;
    428       end if;
    429     end if;
    430   end process; -- bit counter
    431 
    432   tx_end = '1' when master_mode = '1' and bit_ctr = "001"
    433                      and shift_clk = '1' and tx_run = '1' else 
    434             '0'; 
    435   tx_start = '1' when master_mode = '1' and spi_go = '1' else 
    436               '0'; 
    437 
    438   gjr_proc : process (clk)
    439   begin        ---------Control Register----------------------
    440     if (clk'event and clk = '1') then
    441       if (rst = '1') then -- sync reset
    442         ctl_reg = "00000000";
    443       else
    444         if (chip_sel = '1' and write = '1' and addr = "01") then -- load
    445           ctl_reg = datain;
    446         end if;
    447       end if;
    448     end if;
    449   end process;
    450 
    451   -- map the control register to more meaningfull names 
    452   master_mode = ctl_reg(1);
    453   open_drain  = ctl_reg(2);
    454   polck       = ctl_reg(3);
    455   phase       = ctl_reg(4);
    456   sel_clk     = ctl_reg(6 downto 5);
    457 
    458   s_proc : process (clk)
    459   begin  ---------Slave Select Register-------------------------
    460     if (clk'event and clk = '1') then
    461       if (rst = '1') then -- sync reset
    462         ssel = "00000000";
    463       else
    464         if (chip_sel = '1' and write = '1' and addr = "11") then -- load
    465           ssel = datain;
    466         end if;
    467       end if;
    468     end if;
    469   end process;
    470   slvselo = ssel(4 downto 0);    -- drive the port
    471   slvsele = master_mode;
    472 
    473   cf_proc : process (clk)
    474   begin ---------Collision flag bit---------------------------
    475     if (clk'event and clk = '1') then
    476       if (rst = '1') then
    477         col_flag = '0';
    478       else
    479         if (master_mode = '1' and slvsel_r3 = '1') then
    480           col_flag = '1';
    481         elsif (chip_sel = '1' and write = '1'
    482           and addr = "10" and datain(5) = '1') then
    483           col_flag = '0';
    484         end if;
    485       end if;
    486     end if;
    487   end process;
    488 
    489   o_proc : process (clk)
    490   begin ---------OFLOw flag bit------------------------------
    491     if (clk'event and clk = '1') then
    492       if (rst = '1') then
    493         oflow = '0';
    494       else
    495         if (chip_sel = '1' and write = '1' and addr = "00" and
    496             -- write to DOUT 
    497           (tx_run = '1' or slvsel_r3 = '1')) then    -- and we're busy
    498           oflow = '1';
    499         elsif (chip_sel = '1' and write = '1' and addr = "10"
    500           and datain(6) = '1') then
    501           oflow = '0';
    502         end if;
    503       end if;
    504     end if;
    505   end process;
    506 
    507   elr_proc : process (clk)
    508   begin ---------IRQ flag bit------------------------------
    509     if (clk'event and clk = '1') then
    510       if (rst = '1') then
    511         irq_flag = '0';
    512       else
    513         if (tx_end = '1' or (slvsel_r2 = '0' and slvsel_r3 = '1')) then
    514           irq_flag = '1';
    515         elsif (chip_sel = '1' and write = '1' and addr = "10"
    516           and datain(7) = '1') then
    517           irq_flag = '0';
    518         end if;
    519       end if;
    520     end if;
    521   end process;
    522   irq = irq_flag and ctl_reg(7); -- gate with the IRQENB bit.
    523 
    524   flops_proc : process (clk)
    525   begin      ----------------various pipeline flops---------
    526     if (clk'event and clk = '1') then
    527       slvsel_r3   = slvsel_r2;
    528       slvsel_r2   = slvsel_r1;         -- synchronizers
    529       slvsel_r1   = slvsel;
    530       sck_r3      = sck_r2;
    531       sck_r2      = sck_r1;            -- synchronizers
    532       sck_r1      = not scki xor polck;
    533       -- select the desired polarity of the slave clk 
    534       tx_start_r1 = tx_start;
    535     end if;
    536   end process;
    537 
    538   dvd_proc : process (clk)
    539   begin----------------clock divider for clk generation-------
    540     -- create a 2x clock which creates 2 pulses. 
    541     -- One for each edge of SCK. 
    542     if (clk'event and clk = '1') then
    543       if (not (tx_run = '1' and master_mode = '1') or tx_end = '1') then
    544         -- divider only runs when sending data 
    545         dvd_ctr = "00000";
    546         dvd2 = '0';
    547       else
    548         if (dvd_ctr = "00000") then
    549           if (sel_clk = "00") then
    550             dvd_ctr = "00011";
    551           elsif (sel_clk = "01") then
    552             dvd_ctr = "00111";
    553           elsif (sel_clk = "10") then
    554             dvd_ctr = "01111";
    555           else
    556             dvd_ctr = "11111";
    557           end if;
    558           if (tx_start_r1 = '0') then
    559             dvd2 = not dvd2;
    560           end if;
    561         else
    562           dvd_ctr = std_ulogic_vector(unsigned(dvd_ctr)-1);
    563         end if;
    564       end if;
    565     end if;
    566   end process; -- dvd
    567   dvd_zero = '1' when dvd_ctr = "00000" else
    568               '0'; 
    569 
    570   shift_clk = dvd_zero and dvd2 and tx_run and not tx_start_r1
    571                -- TX_START_R1 prevents data from shifting on the first 
    572                -- clock in POLCK=1 mode which we don't want.We only get 
    573                -- 7 clocks otherwise. 
    574   when master_mode = '1' else
    575                sck_r2 and not sck_r3; 
    576 
    577   shift_clk_negedge = dvd_zero and not dvd2 and tx_run
    578                        when master_mode = '1' 
    579                        else not sck_r2 and sck_r3; 
    580 
    581   with addr select
    582     dataout = -- dataout multiplexor for register readback
    583                shift_reg  when "00", 
    584                ctl_reg    when "01", 
    585                status     when "10", 
    586                ssel       when "11", 
    587                "XXXXXXXX" when others; 
    588 
    589   -- assemble the bits that make up the status register 
    590   status = irq_flag & oflow & col_flag & "000" & tx_run & slvsel_r3;
    591 
    592   scke = master_mode;
    593   scko = dvd2 xor polck;
    594 
    595 end rtl;

  • 相关阅读:
    Makefile中的ifeq 多条件使用
    Android引入动态库so的方法
    在Win10上使用Visual Studio2015的Android模拟器
    linux下insmod模块出现“Invalid parameters"
    在干净的ubuntu 14.10上编译Qemu2.2.0的过程
    Windows下struct和union字节对齐设置以及大小的确定(一 简介和结构体大小的确定)
    C++类中一个构造函数调用另一个构造函数
    用汇编语言角度来理解C语言的一些问题
    TCP协议的安全性分析
    MySQL入门,第四部分,学会创建、删除表
  • 原文地址:https://www.cnblogs.com/shangdawei/p/2503729.html
Copyright © 2011-2022 走看看