⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spi_controller.v

📁 a verilog prigram for SPI
💻 V
字号:
module spi_controller(clk,reset,sck_int,sck_int_re,sck_int_fe,                      sck_re,sck_fe,start,done,rec_load,ss_mask_reg,                      /*ss_in_int,*/tx_empty,tx_empty_reset,rec_full,                      rec_full_reset,cpha,cpol,ss_n,/*ss_in_n,*/ss_n_int,                      tx_shift,tx_load,clk0_mask,clk1_mask);                         //mcu interface   input start;                          //start transfer   output done;                          //byte transfer is complete   input rec_load;                       //load control signal to spi receive register   input [7:0]ss_mask_reg;               //uc slave select register   //inout ss_in_int;                      //internal sampled version of ss_in_n needed by                                         //mcu to generate an interrupt   inout tx_empty;                       //flag indicating that spitr is empty   input tx_empty_reset;                 //tx_empty flag reset when spitr is written   output rec_full;                      //flag indicating that spirr has new data   input rec_full_reset;                 //rec_full flag reset when spirr is read   input cpha;                           //clock phase from mcu   input cpol;                           //clock polarity from mcu      //spi interface   output [7:0]ss_n;                     //slave select signals   //input ss_in_n;                        //input slave select indicating master bus contention   inout ss_n_int;                       //slave select register                          //internal interface   input sck_int;                        //internal version of sck with cpha=1   input sck_int_re;                     //indicates rising edge on internal sck   input sck_int_fe;                     //indicates falling edge on internal sck   input sck_re;                         //indicates rising edge on external sck   input sck_fe;                         //indicates falling edge on external sck   output tx_shift;                      //shift control signal to spi xmit shift register   inout tx_load;                        //load control signal to the spi xmit shift register   output clk0_mask;                     //masks cpha=0 version of sck   output clk1_mask;                     //masks cpha=1 version of sck      input clk,reset;      reg done,rec_full,tx_shift,clk0_mask,       clk1_mask;   reg /*ss_in_int_reg,*/tx_empty_reg,tx_load_reg;      //reg ss_in_neg;                        //SS_IN_N sampled with negative edge of clk   //reg ss_in_pos;                        //SS_IN_N sampled with rising edge of clk   //reg [7:0]ss_n_out;                    //output SS_N that are 3-stated if SS_IN_INT   reg cnt_en;                          //count enable for counter   reg cnt_reset;                       //reset for counter from SPI   wire [3:0]cnt;                        //counter output   reg cnt_rst;                          //reset to counter that includes SS_IN_INT      parameter idle=0,assert_ssn1=1,assert_ssn2=2,unmask_sck=3,             xfer_bit=4,assert_done=5,chk_start=6,mask_sck=7,             hold_ssn1=8,hold_ssn2=9,negate_ssn=10;   	reg [3:0]state,next_state;      counter_4bit cnt_4(.clk(sck_int),.clr(cnt_reset),.cnt_en(cnt_en),                      .q(cnt));      //assign ss_in_int=ss_in_int_reg;   assign tx_empty=tx_empty_reg;   assign tx_load=tx_load_reg;   //assign cnt_reset=(cnt_rst==0)?0:1;   assign ss_n_int=((state==idle)||(state==negate_ssn))?1:0;    assign ss_n=~ss_mask_reg;                        //sample ss_in_n signal at posedge   /*always @(posedge clk or negedge reset)      begin         if (!reset)            ss_in_pos<=1;         else             ss_in_pos<=ss_in_n;      end   */     //sample ss_in_n signal at negedge   /*always @(negedge clk or negedge reset)      begin         if (!reset)            ss_in_neg<=1;         else             ss_in_neg<=ss_in_n;      end   */      //generate ss_in_int   /*always @(posedge clk or negedge reset)      begin         if (!reset)            ss_in_int_reg<=1;         else if ((ss_in_pos==0)&&(ss_in_neg==0))                 ss_in_int_reg<=0;              else ss_in_int_reg<=1;      end   */      //spi_sm   always @(posedge clk or negedge reset)      begin         if (!reset)            state<=idle;         else state<=next_state;      end         always @(state,start,cnt,sck_int_re,sck_int_fe,sck_re,            sck_fe,tx_empty,cpha,cpol)      begin         clk0_mask<=0;         clk1_mask<=0;         cnt_en<=0;         cnt_rst<=0;         done<=0;         tx_shift<=0;         tx_load_reg<=0;                  case (state)            idle: begin                     if ((start==1)&&(tx_empty==0))                        next_state<=assert_ssn1;                     else next_state<=idle;                  end                        //this state asserts SS_N and waits for first edge of SCK_INT            //SS_N must be asserted ~1 SCK before SCK is output from chip            assert_ssn1: begin                            if (sck_int_re==1)                               next_state<=assert_ssn2;                            else next_state<=assert_ssn1;                         end                        //this state asserts SS_N and waits for next edge of SCK_INT            //SS_N must be asserted ~1 SCK before SCK is output from chip            assert_ssn2: begin                            if (sck_int_fe==1)                               next_state<=unmask_sck;                            else next_state<=assert_ssn2;                         end                        //UNMASK_SCK State            unmask_sck: begin                           cnt_rst<=1;         //release counter from reset                           cnt_en<=1;          //enable counter                           clk1_mask<=1;       //unmask sck_1                           tx_load_reg<=1;     //load SPI shift register                           if (sck_int_re==1)                              next_state<=xfer_bit;                           else next_state<=unmask_sck;                        end                        //XFER_BIT State            xfer_bit: begin                         cnt_rst<=1;           //release counter from reset                         cnt_en<=1;            //enable counter                         clk0_mask<=1;         //unmask sck_0                         clk1_mask<=1;         //unmask sck_1                         tx_shift<=1;          //enable shifting of SPI shift registers                         if (cnt==8)                            next_state<=assert_done;                         else next_state<=xfer_bit;                      end                        //this state asserts done to the uC so that new data            //can be written into the transmit register or data            //can be read from the receive register            assert_done: begin                            done<=1;                                        clk0_mask<=1;                            clk1_mask<=1;                            tx_shift<=1;                            if (sck_int_fe==1)                               next_state<=chk_start;                            else next_state<=assert_done;                         end                        //CHK_START State            chk_start: begin                          cnt_en<=1;                          cnt_rst<=1;                          clk0_mask<=1;                          clk1_mask<=1;                          done<=1;                          if (cpha==0)                          //when CPHA = 0, have to negate slave select and then                          //re-assert it. Need to wait for last SCK pulse to complete                          //and mask SCK before negating SS_N.                              if (((sck_re==1)&&(cpol==1))||                                ((sck_fe==0)&&(cpol==0)))                                begin                                   clk0_mask<=0;                                   clk1_mask<=0;                                   next_state<=mask_sck;                                end                             //else                             //   begin                             //      clk0_mask<=clk0_mask;                             //      clk1_mask<=clk1_mask;                             //   end                             //CPHA=1 and have more data to transfer, go back to                              //UNMASK_CK state                             else if ((start==1)&&(tx_empty==0))                                     begin                                        clk1_mask<=1;                                        tx_load_reg<=1;                                        next_state<=unmask_sck;                                     end                             else                             //CPHA=1 and no more data to transfer                             //wait for last SCKs and then mask SCK                                begin                                    if (((sck_re==1)&&(cpol==1))||                                      ((sck_fe==0)&&(cpol==0)))                                      begin                                         clk0_mask<=0;                                         clk1_mask<=0;                                         next_state<=mask_sck;                                      end                                    //else                                    //   begin                                    //      clk0_mask<=clk0_mask;                                    //      clk1_mask<=clk1_mask;                                    //   end									//else next_state<=chk_start;                                    clk0_mask<=0;                                    clk1_mask<=1;                                end                       end                        //MASK_SCK State            //wait for next internal SCK edge to help provide SS_N hold time            mask_sck: begin                         if (sck_int_fe==1)                            next_state<=hold_ssn1;                         else next_state<=mask_sck;                      end                        //HOLD_SSN1 State            //This state waits for another SCK edge to provide SS_N hold time            hold_ssn1: begin                          if (sck_int_fe==1)                            next_state<=hold_ssn2;                         else next_state<=hold_ssn1;                       end                        //HOLD_SSN2 State            //This state waits for another SCK edge to provide SS_N hold time            hold_ssn2: begin                          if (sck_int_fe==1)                             next_state<=negate_ssn;                          else next_state<=hold_ssn2;                       end                        //NEGATE_SSN State            //SS_N should negate for an entire SCK This state waits for an SCK edge            negate_ssn: begin                           if (sck_int_fe==1)                              next_state<=idle;                           else next_state<=negate_ssn;                        end            default: next_state<=idle;         endcase      end          //generate tx_empty    always @(posedge sck_int or negedge reset)       begin          if (!reset)             tx_empty_reg<=0;          else if (!tx_empty_reset)                  tx_empty_reg<=0;               else if (tx_load)                       tx_empty_reg<=1;                    //else tx_empty_reg<=tx_empty_reg;       end          //generate rec_full   always @(posedge clk or negedge reset)      begin         if (!reset)            rec_full<=0;         else if (!rec_full_reset)                 rec_full<=0;         else if (rec_load)                 rec_full<=1;              //else rec_full<=rec_full;      end                 //generate ss_n_out   /*always @(posedge clk or negedge reset)      begin         if (!reset)            ss_n_out<=8'b11111111;         else if (ss_n_int==0)                 ss_n_out<=~ss_mask_reg;              else ss_n_out<=8'b11111111;      end   */      always @(cnt_rst,reset)      begin         if (cnt_rst==!reset)            cnt_reset<=0;         else cnt_reset<=1;      end      endmodule                                                                                                                                                                                

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -