博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
altera cpld spi master verilog
阅读量:5959 次
发布时间:2019-06-19

本文共 15512 字,大约阅读时间需要 51 分钟。

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) begin101     if (CS & WR & addr[1] & ~addr[0]) begin102         spi_word_send <=1;103     end else begin104         spi_word_send <=0;105     end106 end107 108 /* Generating the SPI clock */109 always @ (posedge spi_clk_gen) begin110     if (~slave_cs) begin111         sclk = ~sclk;112     end else if (~CPOL) begin113         sclk = 0; 114     end else begin115         sclk = 1;116     end117 end118 119 /* Counting SPI word length */120 always @ (posedge sclk or posedge slave_cs) begin121     if (slave_cs) begin122         count = 0;123     end else begin   124         count = count + 1;125     end126 end127 128 /* Reading, writing SPI registers */129 always @ (posedge pro_clk) begin130     if (CS) begin131         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         endcase137     end138 end139 140 /* Controlling the data out enable */141 always @ (RD or data_out) begin142     if (RD) 143     data_out_en = data_out;144     else145     data_out_en = 8'bz;146 end147 148 assign data_bus = data_out_en;149 150 initial 151 begin152     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 end162 163 endmodule164 165 /********************************************** END ******************************************************************/
/******************************************************************************************* Test Bench for SPI Master* January 2007*******************************************************************************************/`timescale 10ns/1nsmodule SPI_master_test;    wire [7:0] data_bus;     // Bidirectionalwire mosi;               // Output from main modulewire sclk;               // Output from main modulewire [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");      endinitial 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    endendmodule/*************************************** END OF TB ***********************************************************************/

转载地址:http://xpuax.baihongyu.com/

你可能感兴趣的文章
太阳能2017年首季业绩“预喜”
查看>>
火爆:Snapchat成App Store搜索量/频率最高应用
查看>>
大多数漏洞通报前都会先在这里曝光
查看>>
People Power 公司入选中国移动数字家庭联盟,共同推进智能家居战略
查看>>
CYQ.Data 轻量数据层之路 V4.5 版本发布[更好的使用体验,更优的缓存机制]
查看>>
NetApp针对其集群化方案“不值得升级”言论回击Wikibon
查看>>
QQ把游戏放进聊天框,这一点Facebook和微信都没做到
查看>>
在线匿名之父意欲终结“加密战争”
查看>>
WLAN市场销量逐步逼近有线网络
查看>>
SDN市场或许进入了慢热期
查看>>
教你使用Linux系统的Shell脚本维护Oracle
查看>>
浅谈物联网的保障措施
查看>>
力龙信息布局大数据领域
查看>>
大数据巧治职业差评师 生存空间锐减九成
查看>>
天津开展免费无线局域网建设
查看>>
朝鲜最新消息|今天勒索病毒跟朝鲜黑客有关
查看>>
提高信息安全意识对网络勒索病毒说不
查看>>
英国政府可能利用曼彻斯特自杀袭击要求互联网公司破解加密
查看>>
Mozilla 将大幅简化火狐浏览器的同步操作
查看>>
微软加大在 Edge/IE 浏览器上阻止 SHA-1 证书的力度
查看>>