2009.02.03 01:19

2008.07.31 - SPI_Verilog(2)

SPI_Verilog(2)
조회(298)
Study - VerilogHDL | 2008/07/31 (목) 15:02
추천 | 스크랩
SPI Verilog(1) 에서는 설계전에 필요한 spec 을 정의하였다.
이번회에서는 Coding 에 들어가보자.
 
Contents( SPI Verilog(1) )
0.     TestVector Block Diagram.
1.     Task( SPI Verilog 입력 모델링 )
2.     Task Write
3.     Task Read
4.  Task Top
 
0.     TestVector Block Diagram.
SPI Verilog coding 하기 위에서, SPI Verilog 입력 모델링이 필요하다. 이번 coding 에서는 Task 를 사용하여, SPI Verilog 입력을 모델링 한다.



1. Task( SPI Verilog 입력 모델링 )
SPI 설명에서 보왔던 SPI Wave form 이다. 이와 같은 형태의 SPI_WRITE task SPI_READ Task 를 만든다.









2.
    
Task Write
아래 Source file 은 위에서 설명한 SPI Write 모델에 대한 Task 를 작성한 것이다.
 
//Source Code
task ts_write;
    input   [ 6:0]    addr;
    input   [ 7:0]    data;
             begin
                      // IDLE
                         repeat(1) @(negedge clk)
                             begin
                             o_spi_ck                       = 1'b0                 ;
                             o_spi_di                       = 1'b0                 ;
                             o_spi_en                     = 1'b0                        ;
                             end
 
                     // Mode = Write
                         repeat(1) @(negedge clk)
                             begin
                             o_spi_ck                       = 1'b1                 ;
                             o_spi_di                       = 1'b0                 ;
                             o_spi_en                     = 1'b0                        ;
                             end
 
                         repeat(1) @(posedge clk)                  o_spi_ck                      = 1'b0             ;
                    
                     // Address
                     for ( i = 7 ; i > 0 ; i=i-1 )
                         begin
                        
                         repeat(1) @(negedge clk)
                             begin
                             o_spi_ck                       = 1'b1                 ;
                             o_spi_di                       = addr[i-1]                   ;
                             o_spi_en                     = 1'b0                        ;
                             end
           
                         repeat(1) @(posedge clk)                  o_spi_ck                      = 1'b0             ;
                        
                         end
       
        // Data
        for ( i = 8 ; i > 0 ; i=i-1 )
                         begin
                        
                         repeat(1) @(negedge clk)
                             begin
                             o_spi_ck                       = 1'b1                 ;
                             o_spi_di                       = data[i-1]                   ;
                             o_spi_en                     = 1'b0             ;
                             end
           
                         repeat(1) @(posedge clk)                  o_spi_ck                      = 1'b0             ;
                        
                         end           
 
                     // IDLE
        repeat(1) @(negedge clk)
                         begin
                         o_spi_ck                            = 1'b0                 ;
                         o_spi_di                            = 0                                ;
                         o_spi_en                          = 1'b0             ;
                         end
                        
                     repeat(1) @(posedge clk)
                         begin
                         o_spi_ck                            = 1'b0                 ;
                         o_spi_di                            = 0                                ;
                         o_spi_en                          = 1'b1             ;
                         end
           end
 
endtask
 
3. Task Read
아래 Source file 은 위에서 설명한 SPI Read 모델에 대한 Task 를 작성한 것이다.
 
//source file
task ts_read;
   
    input   [ 6:0]    addr;
    input   [ 7:0]    data;
          
           begin
 
                     // IDLE
                         repeat(1) @(negedge clk)
                             begin
                             o_spi_ck                       = 1'b0                 ;
                             o_spi_di                       = 1'b0                 ;
                             o_spi_en                     = 1'b0                        ;
                             end
                            
                     // Mode = Read
                         repeat(1) @(negedge clk)
                             begin
                             o_spi_ck                       = 1'b1             ;
                             o_spi_di                       = 1'b1       ;
                             o_spi_en                     = 1'b0             ;
                             end
                        
                                repeat(1) @(posedge clk)            o_spi_ck                      = 1'b0             ;
                    
                     // Address
                     for ( i = 7 ; i > 0 ; i=i-1 )
                         begin
                        
                         repeat(1) @(negedge clk)
                             begin
                             o_spi_ck                       = 1'b1                 ;
                             o_spi_di                       = addr[i-1]                   ;
                             o_spi_en                     = 1'b0             ;
                             end
           
                         repeat(1) @(posedge clk)                  o_spi_ck                      = 1'b0             ;
                        
                         end
       
        // Data
        for ( i = 8 ; i > 0 ; i=i-1 )
                         begin
                        
                         repeat(1) @(negedge clk)
                             begin
                             o_spi_ck                       = 1'b1                 ;
                             o_spi_di                       = data[i-1]                   ;
                             o_spi_en                     = 1'b0                        ;
                             end
           
                         repeat(1) @(posedge clk)                  o_spi_ck                      = 1'b0             ;
                        
                         end           
       
        repeat(1) @(negedge clk)
                         begin
                         o_spi_ck                            = 1'b0                 ;
                         o_spi_di                            = 0                                ;
                         o_spi_en                          = 1'b0             ;
                         end
                        
                     repeat(1) @(posedge clk)
                         begin
                         o_spi_ck                            = 1'b0                 ;
                         o_spi_di                            = 0                                ;
                         o_spi_en                          = 1'b1                        ;
                         end
           end     
endtask

 
4.  Task TOP
 
아래 Source file 은 위에서 설명한 SPI Write, SPI Read 를 하나의 Task 로 작성한 것이다.
 
//Source file
`timescale 1ns / 10ps
 
module  Task_SPI    (
            clk,
           
            o_spi_ck,
            o_spi_di,
            o_spi_en
);
 
//-----------------------------------------------------------------------------
input                                    clk                                       ;
//-----------------------------------------------------------------------------
output                                  o_spi_ck           ;
output                                  o_spi_di            ;
output                                  o_spi_en                     ;
//-----------------------------------------------------------------------------
reg                                                 o_spi_ck           ;
reg                                                 o_spi_di            ;
reg                                                 o_spi_en                     ;
//-----------------------------------------------------------------------------
integer             i               ;
//-----------------------------------------------------------------------------
 
initial
          
           begin
                     o_spi_ck           = 1'b0                        ;
                     o_spi_di            = 1'b0                        ;
                     o_spi_en                     = 1'b1                        ;
                     #1;
                     $display("\nINFO: SPI MODEL INSTANTIATED (%m)\n");
           end
 
 
//-----------------------------------------------------------------------------
// Write task
//-----------------------------------------------------------------------------
task ts_write;
 
 
//-----------------------------------------------------------------------------
// Read task
//-----------------------------------------------------------------------------
task ts_read;
 
endmodule
 

'옛집 > Study - Verilog HDL' 카테고리의 다른 글

2008.07.31 - SPI_Verilog(2)  (0) 2009.02.03
2008.07.31 - SPI_Verilog(1)  (0) 2009.02.03
2008.07.29 - SPI (serial peripheral interface)  (0) 2009.02.03
trackback 0 comment 0
2009.02.03 01:13

2008.07.31 - SPI_Verilog(1)

SPI_Verilog(1)
조회(243)
Study - VerilogHDL | 2008/07/31 (목) 12:32
추천 | 스크랩
SPI Slave verilog 로 만들어 보자.
가상이 칩을 가정하고 interface, Register map 을 설정한다.
 
Contents( SPI Verilog(1) )
0.     SPI Slave Block Diagram.
1.     SPI Slave Interface
2.     SPI Register Map
 
0 . SPI Slave block Diagram
SPI Slave 의 경우 아래 그림과 같이 SPI interface 를 통해 전달 받은 data chip 내부 블록에 전달해 주는 역할을 한다.





1.
    
SPI Slave Interface
 
SPI Interface
SI_CK    : 1-Bit, Input, SPI Interface clock
SI_EN    : 1-Bit, Input, SPI Interface enable, negative enable
SI_DI     : 1-Bit, Input, SPI Interface Data Input
SI_DO    : 1-Bit, Output, SPI Interface Data Output.
 
Register Interface
Reg_0    : 8-Bit, Output
Reg_1    : 8-Bit, Output
Reg_2    : 8-Bit, Output
Reg_3    : 8-Bit, Output
Reg_4    : 8-Bit, Output
Reg_5    : 8-Bit, Output
Reg_6    : 8-Bit, Output
Reg_7    : 8-Bit, Output
 
2.     Register Map







'옛집 > Study - Verilog HDL' 카테고리의 다른 글

2008.07.31 - SPI_Verilog(2)  (0) 2009.02.03
2008.07.31 - SPI_Verilog(1)  (0) 2009.02.03
2008.07.29 - SPI (serial peripheral interface)  (0) 2009.02.03
trackback 0 comment 0
2009.02.03 01:11

2008.07.29 - SPI (serial peripheral interface)

 

 

SPI (serial peripheral interface)
조회(629)
Study - VerilogHDL | 2008/07/29 (화) 22:08
추천 | 스크랩
 
SPI (serial peripheral interface) ; 주변장치용 직렬 인터페이스
SPI는 두 개의 주변장치간에 직렬 통신으로 데이터를 교환할 수 있게 해주는 인터페이스로서, 그 중 하나가 주가 되고 다른 하나가 종이 되어 동작한다. SPI는 전이중 방식으로 동작하는데, 이는 데이터가 양방향으로 동시에 전달될 수 있음을 의미한다. SPI는 대부분 CPU와 주변장치들간에 통신을 하는 시스템에 주로 채용되지만, 두 개의 마이크로프로세서들 사이를 SPI의 형태로 연결하는 것도 가능하다. 이 용어는 원래 모토롤라에서 만들어졌으며, National Semiconductor라는 회사에서는 이와 동일한 인터페이스를 "마이크로와이어"라고 부른다.
직렬 인터페이스는 병렬 인터페이스에 비해 몇 가지 장점이 있다. 그 중 가장 큰 장점은 배선이 간단해진다는 것이다. 그 외에 직렬 인터페이스용 전선을 병렬 인터페이스용 전선에 비해 더 길게 만들 수 있는데, 이는 전선 내부의 도선들 간에 누화 등과 같은 간섭이 훨씬 덜하기 때문이다.
SPI에 의해 제어될 수 있는 주변장치들로는 시프트 레지스터, 메모리 칩, 포트 확장기, 디스플레이 드라이버, 데이터 변환기, 프린터, 데이터 저장장치, 센서, 마이크로프로세서 등 여러 가지 형식들이 있다. 데이터가 전선을 통해 시프트 레지스터에 직렬방식으로 들어가면, 각 부시스템에는 병렬처리의 형식으로 전달된다.
 
위사이트에 나와 있는것처럼 SPI 는 모토롤라에서 만들어 졌으며, MCU 에서 컨트롤할수 있는 주변장치를 제어하는데 쓰인다. 즉, SPI 는 간단한(4-pin) 직렬 인터페이스를 통한 저속의 주변장치 제어에 목적이 있다. ( SPI, I2C 등의 직렬 인터페이스들은 모두 저속에 속한다. )
 
1. General Operation of the SPI
 
The serial port is a flexible, serial communications port, allowing easy interface to many industry-standard microcontrollers and microprocessors.
 
By default, the serial port accepts data in MSB first mode and uses four pins: SI_EN, SI_CK, SI_DI and SI_DO by default.
  SI_EN is a serial clock enable pin;
  SI_CK is the serial clock pin;
  SI_DI is a input data line;
  SI_DO is a serial output pin.
 
SI_EN is an active low control gating read and write cycles. When SI_EN is high, SI_DI and SI_DO go into a high impedance state.
SI_CK is used to synchronize SPI reads and writes at a maximum bit rate of 30 MHz.
Input data is captured on the falling edge, and output data transitions are propagated on the rising edge of the SI_CK signal.
During write operations, the registers are updated after the 16th rising clock edge. Incomplete write operations are ignored.
SI_DI is an input data only pin.
SI_DO is a serial output data pin used for readback operations in 4-wire mode.
 
2. Write Operation

 



WRITE Operation 의 경우, ( 1.Generatio Operation ) 에서 설명한 것과 같이 SI_CK 의 falling edge 에서 data 를 capture 한다. 그리고, Address, Data 모두 MSB 부터 전송한다. ( 위 그림은 SPI Slave 관점에서 그린것이다. )
 
 
3. Read Operation

 







위 그림은 Slave 관점의 그림으로, SI_DO 를 제외한 나머지 3개의 signal 은 Master 에서 전송하는 것이고, SI_DO 는 Slave 에서 전송하는 signal 이다. 여기에서도, Master 에서 전송하는 Data 는 SI_CK 의 falling edge 에서 data 를 capture 한다. 그러나, Slave 에서 전송하는 SI_DO 의 경우 rising edge 에서 전송한다. 그리고, Address, Data 모두 MSB 부터 전송한다.
위 두 그림을 설명하면서 관점 운운 했지만, SI_DO 는 Slave 에서 전송하는 signal 이고, 나머지는 Master 에서 전송하는 signal 이다.
 
 그러나, 이 예제에서 보이는 Address7-bit, Data 8-bit 그리고, SI_EN 의 Active Low 는 고정된 규격(specification) 이 아니다. 앞에서 언급된 것처럼 모토롤라에 의해 만들어진 SPI 는 4-wire, SI_CK, SI_DI, SI_DO, SI_EN 을 이용한 통신을 의미하고, 그 내부의 동작( SI_EN 의 Active Polarity, Address bit, Data bit,등등...) 은 사용자, SPI Slave(MCU 에 의해서 Control 되는 주변 장치) 에 의해 규정된다.
 SPI 를 공부하고 싶은 학생이라면, SPI 를 사용하는 여러 칩들의 manual 을 보고, 다른 chip 들은 어떻게 동작시키는지 살펴본다면 많은 도움이 될거라고 본다.
 

'옛집 > Study - Verilog HDL' 카테고리의 다른 글

2008.07.31 - SPI_Verilog(2)  (0) 2009.02.03
2008.07.31 - SPI_Verilog(1)  (0) 2009.02.03
2008.07.29 - SPI (serial peripheral interface)  (0) 2009.02.03
trackback 0 comment 0


티스토리 툴바