zoukankan      html  css  js  c++  java
  • altera cpld spi master verilog

      1 /***********************************************************************************************
      2 * SPI MASTER
      3 * January 2007
      4 ************************************************************************************************/
      5 `timescale 10ns/1ns
      6 module SPI_Master ( miso, mosi, sclk, ss, data_bus, CS, addr, pro_clk, WR, RD);
      7 
      8 inout [7:0] data_bus;           // 8 bit bidirectional data bus
      9 input pro_clk;                  // Host Processor clock
     10 input miso;                     // Master in slave out
     11 input [1:0] addr;               // A1 and A0, lower bits of address bus
     12 input CS;                       // Chip Select
     13 input WR, RD;                   // Write and read enables
     14 
     15 output mosi;                    // Master out slave in
     16 output sclk;                    // SPI clock
     17 output [7:0] ss;                // 8 slave select lines
     18 
     19 reg [7:0] shift_register;        // Shift register
     20 reg [7:0] txdata;                // Transmit buffer
     21 reg [7:0] rxdata;                // Receive buffer
     22 reg [7:0] data_out;              // Data output register
     23 reg [7:0] data_out_en;           // Data output enable 
     24 reg [7:0] control, status;       // Control Register COntrols things like ss, CPOL, CPHA, clock divider
     25                                  // Status Register is a dummy register never used.
     26 
     27 reg [7:0] clk_divide;            // Clock divide counter
     28 reg [3:0] count;                 // SPI word length counter
     29 reg sclk;                        
     30 reg slave_cs;                    // Slave cs flag
     31 reg mosi;                  // Master out slave in
     32 reg spi_word_send;               // Will send a new spi word.
     33 
     34 wire [7:0] data_bus;
     35 wire [7:0] data_in = data_bus;
     36 wire spi_clk_gen;
     37 wire [2:0] divide_factor = control[2:0];
     38 wire CPOL = control[3];          
     39 wire CPHA = control[4];
     40 wire [7:0]ss; 
     41 
     42 
     43 /* Slave Select lines */
     44 assign ss[7] = ~( control[7] &  control[6] &  control[5] & (~slave_cs)); 
     45 assign ss[6] = ~( control[7] &  control[6] & ~control[5] & (~slave_cs)); 
     46 assign ss[5] = ~( control[7] & ~control[6] &  control[5] & (~slave_cs)); 
     47 assign ss[4] = ~( control[7] & ~control[6] & ~control[5] & (~slave_cs)); 
     48 assign ss[3] = ~(~control[7] &  control[6] &  control[5] & (~slave_cs)); 
     49 assign ss[2] = ~(~control[7] &  control[6] & ~control[5] & (~slave_cs)); 
     50 assign ss[1] = ~(~control[7] & ~control[6] &  control[5] & (~slave_cs)); 
     51 assign ss[0] = ~(~control[7] & ~control[6] & ~control[5] & (~slave_cs)); 
     52 
     53 /* clock divide */
     54 assign spi_clk_gen = clk_divide[divide_factor];
     55 
     56 /* Clock Divider */
     57 always @ (negedge pro_clk) begin
     58     clk_divide = clk_divide + 1;     
     59 end
     60 
     61 /* Reading the miso line and shifting */
     62 always @ (posedge (sclk ^ (CPHA ^ CPOL)) or posedge spi_word_send) begin
     63     if (spi_word_send) begin
     64         shift_register[7:0] = txdata;
     65     end else begin 
     66         shift_register = shift_register << 1;
     67         shift_register[0] <= miso;
     68     end
     69 end
     70 
     71 /* Writing the mosi */
     72 always @ (negedge (sclk ^ (CPHA ^ CPOL)) or posedge spi_word_send) begin
     73     if (spi_word_send) begin
     74         mosi = txdata[7];
     75     end else begin 
     76         mosi = shift_register[7];
     77     end
     78 end
     79 
     80 /* Contolling the interrupt bit in the status bit */
     81 always @ (posedge slave_cs or posedge spi_word_send) begin
     82     if (spi_word_send) begin
     83         status[0] = 0;
     84     end else begin
     85       status = 8'h01;
     86     rxdata = shift_register;         // updating read buffer
     87   end
     88 end
     89    
     90 /* New SPI wrod starts when the transmit buffer is updated */
     91 always @ (posedge pro_clk) begin
     92     if (spi_word_send) begin
     93         slave_cs <= 0;
     94     end else if ((count == 8) & ~(sclk ^ CPOL)) begin
     95         slave_cs <= 1;
     96     end    
     97 end
     98 
     99 /* New Spi word is intiated when transmit buffer is updated */
    100 always @ (posedge pro_clk) begin
    101     if (CS & WR & addr[1] & ~addr[0]) begin
    102         spi_word_send <=1;
    103     end else begin
    104         spi_word_send <=0;
    105     end
    106 end
    107 
    108 /* Generating the SPI clock */
    109 always @ (posedge spi_clk_gen) begin
    110     if (~slave_cs) begin
    111         sclk = ~sclk;
    112     end else if (~CPOL) begin
    113         sclk = 0; 
    114     end else begin
    115         sclk = 1;
    116     end
    117 end
    118 
    119 /* Counting SPI word length */
    120 always @ (posedge sclk or posedge slave_cs) begin
    121     if (slave_cs) begin
    122         count = 0;
    123     end else begin   
    124         count = count + 1;
    125     end
    126 end
    127 
    128 /* Reading, writing SPI registers */
    129 always @ (posedge pro_clk) begin
    130     if (CS) begin
    131         case (addr) 
    132         2'b00 : if (WR) control <= data_in;
    133         2'b01 : if (RD) data_out <= status;   // Void 
    134       2'b10 : if (WR) txdata <= data_in;
    135       2'b11 : if (RD) data_out <= rxdata;
    136         endcase
    137     end
    138 end
    139 
    140 /* Controlling the data out enable */
    141 always @ (RD or data_out) begin
    142     if (RD) 
    143     data_out_en = data_out;
    144     else
    145     data_out_en = 8'bz;
    146 end
    147 
    148 assign data_bus = data_out_en;
    149 
    150 initial 
    151 begin
    152     mosi = 0;
    153     //sclk = 0;
    154     control = 0;
    155     count = 0;
    156     slave_cs = 1;
    157     txdata = 0;
    158     rxdata = 0;
    159     clk_divide = 0;
    160     data_out = 0;
    161 end
    162 
    163 endmodule
    164 
    165 /********************************************** END ******************************************************************/
    /******************************************************************************************
    * Test Bench for SPI Master
    * January 2007
    *******************************************************************************************/
    
    `timescale 10ns/1ns
    
    module SPI_master_test;
        
    wire [7:0] data_bus;     // Bidirectional
    wire mosi;               // Output from main module
    wire sclk;               // Output from main module
    wire [7:0] ss;           // Output from main module
    
    /* Inputs to main module */
    reg miso;               
    reg CS;
    reg [1:0] addr;
    reg pro_clk;
    reg WR,RD;
    
    SPI_Master tb ( miso, mosi, sclk, ss, data_bus, CS, addr, pro_clk, WR, RD);
    
    /* Internal registers defined for TB */
    reg [7:0] data_send;
    reg [7:0] transmit_store;
    reg [7:0] data_receive;
    reg [7:0] miso_data;
    reg [7:0] mosi_data;
    
    assign data_bus = data_send;
    
    initial                         // Generates serial clock of time period 10
      begin
        pro_clk = 0;
        forever #5 pro_clk = !pro_clk;
      end
      
    initial 
      begin
        CS = 0;
        RD = 0;
        WR = 0;
        data_send = 0;
        addr = 0;
        miso = 0;
        
        #20
        /* Updating Control register */
        @ (negedge pro_clk)
        CS = 1;
        WR = 1;
        data_send = 0;            
        addr = 0;
        /* Updating Transmit buffer */
        @ (negedge pro_clk)
        CS = 1;
        WR = 1;
        data_send = $random; 
        addr = 2'b10;
        #1 transmit_store = data_send;
        @ (negedge pro_clk)
        $display ("Transmit Buffer loaded");
        $display ("SS[0] = 0, CPHA = 0, CPOL = 0 at time:",$time);
        $display ("Observe Waveform for spi clock frequency, spi data changing at falling egde, valid at rising edge");
        CS = 0;
        WR = 0;
        data_send = 8'bz;
        
        @ (posedge ss[0])
        #20
        
        /* Checking Status */
        @ (negedge pro_clk)
        CS = 1;
        RD = 1;
        addr = 2'b01;
        @ (negedge pro_clk)
        data_receive = data_bus;
        @ (negedge pro_clk)
        if (data_receive[0]) begin
            $display("Interrupt detected at time:", $time);
            addr = 2'b11;
        end else begin
            $display("Interrupt detect failed at time:", $time);
        end
        @ (negedge pro_clk)
        data_receive = data_bus;
        if (data_bus == miso_data) begin
            $display("Data received from spi slave verified", $time);
        end else begin
            $display("Data receive failed",$time);
        end
        /* Writing new control word */
        @ (negedge pro_clk)
        CS = 1;
        WR = 1;
        RD = 0;
        data_send = 8'b10001001;            
        addr = 0;
        @ (negedge pro_clk)
        CS = 1;
        WR = 1;
        data_send = $random; 
        addr = 2'b10;
        #1 transmit_store = data_send;
        @ (negedge pro_clk)
        $display ("\n Transmit Buffer reloaded");
        $display ("Observe Waveform for spi clock frequency, spi data changing at rising edge and valid at falling edge");
        $display ("SS[4] = 0, CPHA = 0, CPOL = 1 at time:",$time);
        CS = 0;
        RD = 0;
        WR = 0;
        data_send = 8'bz;
        
        @ (posedge ss[4])
        #20
        
        /* Checking Status */
        @ (negedge pro_clk)
        CS = 1;
        RD = 1;
        addr = 2'b01;
        @ (negedge pro_clk)
        data_receive = data_bus;
        @ (negedge pro_clk)
        if (data_receive[0]) begin
            $display("Interrupt detected at time:", $time);
            addr = 2'b11;
        end else begin
            $display("Interrupt detect failed at time:", $time);
        end
        @ (negedge pro_clk)
        data_receive = data_bus;
        if (data_bus == miso_data) begin
            $display("Data received from spi slave verified", $time);
        end else begin
            $display("Data receive failed",$time);
        end
        /* Writing new control word */
        @ (negedge pro_clk)
        CS = 1;
        WR = 1;
        RD = 0;
        data_send = 8'b11110010;            
        addr = 0;
        @ (negedge pro_clk)
        CS = 1;
        WR = 1;
        data_send = $random; 
        addr = 2'b10;
        #1 transmit_store = data_send;
        @ (negedge pro_clk)
        $display ("\n Transmit Buffer reloaded");
        $display ("Observe Waveform for spi clock frequency, spi data changing at rising edge and valid at falling edge");
        $display ("SS[7] = 0, CPHA = 1, CPOL = 0 at time:",$time);
        CS = 0;
        RD = 0;
        WR = 0;
        data_send = 8'bz;
        
        @ (posedge ss[7])
        #20
        
        /* Checking Status */
        @ (negedge pro_clk)
        CS = 1;
        RD = 1;
        addr = 2'b01;
        @ (negedge pro_clk)
        data_receive = data_bus;
        @ (negedge pro_clk)
        if (data_receive[0]) begin
            $display("interrupt detected at time:", $time);
            addr = 2'b11;
        end else begin
            $display("interrupt detect failed at time:", $time);
        end
        @ (negedge pro_clk)
        data_receive = data_bus;
        if (data_bus == miso_data) begin
            $display("Data received from spi slave verified", $time);
        end else begin
            $display("Data receive failed",$time);
        end
        /* Writing new control word */
        @ (negedge pro_clk)
        CS = 1;
        WR = 1;
        RD = 0;
        data_send = 8'b01111100;            
        addr = 0;
        @ (negedge pro_clk)
        CS = 1;
        WR = 1;
        data_send = $random; 
        addr = 2'b10;
        #1 transmit_store = data_send;
        @ (negedge pro_clk)
        $display ("\n Transmit Buffer reloaded");
        $display ("Observe Waveform for spi clock frequency, spi data changing at falling edge and valid at rising edge");
        $display ("SS[3] = 0, CPHA = 1, CPOL = 1 at time:",$time);
        CS = 0;
        RD = 0;
        WR = 0;
        data_send = 8'bz;
        
        @ (posedge ss[3])
        #20
        
        /* Checking Status */
        @ (negedge pro_clk)
        CS = 1;
        RD = 1;
        addr = 2'b01;
        @ (negedge pro_clk)
        data_receive = data_bus;
        @ (negedge pro_clk)
        if (data_receive[0]) begin
            $display("Interrupt detected at time:", $time);
            addr = 2'b11;
        end else begin
            $display("Interrupt detect failed at time:", $time);
        end
        @ (negedge pro_clk)
        data_receive = data_bus;
        if (data_bus == miso_data) begin
            $display("Data received from spi slave verified", $time);
        end else begin
            $display("Data receive failed",$time);
        end
        @ (negedge pro_clk)
        $display ("\n PASS: hit break to stop simulation");
          
    end
    
    initial 
    begin
        /* Writing MISO / Reading MOSI for random values */
        #20
        miso_data = $random;
        @ (negedge ss[0])
        miso = miso_data[7];
        @ (posedge sclk)
        mosi_data[7] = mosi; 
        @ (negedge sclk)
        miso = miso_data[6];
        @ (posedge sclk)
        mosi_data[6] = mosi;
        @ (negedge sclk)
        miso = miso_data[5];
        @ (posedge sclk)
        mosi_data[5] = mosi;
        @ (negedge sclk)
        miso = miso_data[4];
        @ (posedge sclk)
        mosi_data[4] = mosi;
        @ (negedge sclk)
        miso = miso_data[3];
        @ (posedge sclk)
        mosi_data[3] = mosi;
        @ (negedge sclk)
        miso = miso_data[2];
        @ (posedge sclk)
        mosi_data[2] = mosi;
        @ (negedge sclk)
        miso = miso_data[1];
        @ (posedge sclk)
        mosi_data[1] = mosi;
        @ (negedge sclk)
        miso = miso_data[0];
        @ (posedge sclk)
        mosi_data[0] = mosi;
        #5 
        if(mosi_data == transmit_store) begin
            $display("Data transmitted to spi slave verified", $time );
        end else begin
            $display("Data Transmit to spi slave failed !", $time );
        end
        
        /* Next set : CPOL = 1, CPHA = 0 */        
        @ (negedge ss[4])
        miso_data = $random;
        miso = miso_data[7];
        @ (negedge sclk)
        mosi_data[7] = mosi; 
        @ (posedge sclk)
        miso = miso_data[6];
        @ (negedge sclk)
        mosi_data[6] = mosi;
        @ (posedge sclk)
        miso = miso_data[5];
        @ (negedge sclk)
        mosi_data[5] = mosi;
        @ (posedge sclk)
        miso = miso_data[4];
        @ (negedge sclk)
        mosi_data[4] = mosi;
        @ (posedge sclk)
        miso = miso_data[3];
        @ (negedge sclk)
        mosi_data[3] = mosi;
        @ (posedge sclk)
        miso = miso_data[2];
        @ (negedge sclk)
        mosi_data[2] = mosi;
        @ (posedge sclk)
        miso = miso_data[1];
        @ (negedge sclk)
        mosi_data[1] = mosi;
        @ (posedge sclk)
        miso = miso_data[0];
        @ (negedge sclk)
        mosi_data[0] = mosi;
        #5 
        if(mosi_data == transmit_store) begin
            $display("Data transmitted to spi slave verified", $time );
        end else begin
            $display("Data Transmit to spi slave failed !", $time );
        end
        
        /* Next set : CPOL = 0, CPHA = 1 */        
        @ (negedge ss[7])
        miso_data = $random;
        @ (posedge sclk)
        miso = miso_data[7];
        @ (negedge sclk)
        mosi_data[7] = mosi; 
        @ (posedge sclk)
        miso = miso_data[6];
        @ (negedge sclk)
        mosi_data[6] = mosi;
        @ (posedge sclk)
        miso = miso_data[5];
        @ (negedge sclk)
        mosi_data[5] = mosi;
        @ (posedge sclk)
        miso = miso_data[4];
        @ (negedge sclk)
        mosi_data[4] = mosi;
        @ (posedge sclk)
        miso = miso_data[3];
        @ (negedge sclk)
        mosi_data[3] = mosi;
        @ (posedge sclk)
        miso = miso_data[2];
        @ (negedge sclk)
        mosi_data[2] = mosi;
        @ (posedge sclk)
        miso = miso_data[1];
        @ (negedge sclk)
        mosi_data[1] = mosi;
        @ (posedge sclk)
        miso = miso_data[0];
        @ (negedge sclk)
        mosi_data[0] = mosi;
        #5 
        if(mosi_data == transmit_store) begin
            $display("Data transmitted to spi slave verified", $time );
        end else begin
            $display("Data Transmit to spi slave failed !", $time );
        end
        
        /* Next set : CPOL = 1, CPHA = 1 */        
        @ (negedge ss[3])
        miso_data = $random;
        @ (negedge sclk)
        miso = miso_data[7];
        @ (posedge sclk)
        mosi_data[7] = mosi; 
        @ (negedge sclk)
        miso = miso_data[6];
        @ (posedge sclk)
        mosi_data[6] = mosi;
        @ (negedge sclk)
        miso = miso_data[5];
        @ (posedge sclk)
        mosi_data[5] = mosi;
        @ (negedge sclk)
        miso = miso_data[4];
        @ (posedge sclk)
        mosi_data[4] = mosi;
        @ (negedge sclk)
        miso = miso_data[3];
        @ (posedge sclk)
        mosi_data[3] = mosi;
        @ (negedge sclk)
        miso = miso_data[2];
        @ (posedge sclk)
        mosi_data[2] = mosi;
        @ (negedge sclk)
        miso = miso_data[1];
        @ (posedge sclk)
        mosi_data[1] = mosi;
        @ (negedge sclk)
        miso = miso_data[0];
        @ (posedge sclk)
        mosi_data[0] = mosi;
        #5 
        if(mosi_data == transmit_store) begin
            $display("Data transmitted to spi slave verified", $time );
        end else begin
            $display("Data Transmit to spi slave failed !", $time );
        end
        
    end
    
    endmodule
    
    /*************************************** END OF TB ***********************************************************************/

  • 相关阅读:
    班级派团队项目小计(七)
    班级派团队项目小计(六)
    班级派团队项目小计(五)
    班级派团队项目小计(四)
    班级派团队项目小计(三)
    场景描述思密达~
    班级派团队项目小计(二)
    班级派团队项目小计(一)
    构建之法阅读笔记02
    JS获取坐标
  • 原文地址:https://www.cnblogs.com/shangdawei/p/2503511.html
Copyright © 2011-2022 走看看