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

📄 config_dac.v.bak

📁 Verilog实现 spi接口的FPGA实现 通过仿真
💻 BAK
字号:
module config_dac(
    clk,
    resetb,
   
    wr_rd_addr,
    wr_en,
    wr_data,
    rd_en,
    rd_data,
    rd_data_valid,
    busy,

    spi_ncs,
    spi_sdio,
    spi_sdo,
    spi_sck
);

input        clk,resetb;
input [4:0]  wr_rd_addr;
input        wr_en;
input [7:0]  wr_data;
input        rd_en;
output [7:0] rd_data;
output       rd_data_valid;
output       busy;

output       spi_ncs;
output       spi_sdio;
input        spi_sdo;
output       spi_sck;

wire       clk,resetb;
wire [4:0] wr_rd_addr;
wire       wr_en;
wire [7:0] wr_data;
wire       rd_en;
reg  [7:0] rd_data;
reg        rd_data_valid;
reg        busy;
reg        spi_ncs;
wire       spi_sdio;
wire       spi_sdo;
reg        spi_sck;

reg  [4:0] main_state,next_state;
parameter IDLE=5'b0_0001,
          START=5'b0_0010,
          INSTRUCTION=5'b0_0100,
          DATA=5'b0_1000,
          STOP=5'b1_0000;

reg [4:0]  waddr;
reg [7:0]  data_received;
reg [7:0]  data_to_send;
reg        sdo_in;
reg        read_flag;
reg [8:0]  bit_transfered;
reg [1:0]  sck_count;
reg [7:0]  wdata;

always @(posedge clk)
  sdo_in<=spi_sdo;

always @(posedge clk)
  if(wr_en==1 || rd_en==1)
    waddr<=wr_rd_addr;

always @(posedge clk)
  if(wr_en==1)
    wdata<=wr_data;

always @(posedge clk)
  if(wr_en==1)
    read_flag<=0;
  else if(rd_en==1)
    read_flag<=1;

always @(posedge clk or negedge resetb)
  if(!resetb)
    main_state<=IDLE;
  else
    main_state<=next_state;

always @*
begin
  case(main_state)
  IDLE:
    if(wr_en==1 || rd_en==1)
      next_state=START;
    else 
      next_state=IDLE;
  START:
     if(sck_count==1)
       next_state=INSTRUCTION;
     else 
       next_state=START;
  INSTRUCTION:
     if(bit_transfered[8]==1)
       next_state=DATA;
     else 
       next_state=INSTRUCTION;
  DATA:
     if(bit_transfered[7]==1 && sck_count==1)
       next_state=STOP;
     else 
       next_state=DATA;
  STOP:
     if(sck_count==1)
       next_state=IDLE;
     else 
       next_state=STOP;
  default:
     next_state=IDLE;
  endcase
end

always @(posedge clk)
  if(main_state==IDLE)
    sck_count<=0;
  else
    sck_count<=sck_count+1;

always @(posedge clk)
  if(main_state==IDLE)
    spi_ncs<=1;
  else if(main_state==START && sck_count==1)
    spi_ncs<=0;
  else if(main_state==STOP && sck_count==2)
    spi_ncs<=1;


always @(posedge clk)
  if(main_state==IDLE || main_state==STOP)
    spi_sck<=1;
  else if(sck_count==2)
    spi_sck<=0;
  else if(sck_count==0)
    spi_sck<=1;

always @(posedge clk)
  if(main_state==INSTRUCTION && bit_transfered[0]==1)
  begin
    if(read_flag==1)
      data_to_send<={3'b0,waddr};
    else
      data_to_send<={3'b100,waddr};
  end
  else if(main_state==DATA && bit_transfered[8]==1)
      data_to_send<=wdata;
  else if(sck_count==2)
      data_to_send<={data_to_send[6:0],1'b0};

assign spi_sdio=data_to_send[7];

always @(posedge clk)
  if(main_state==IDLE)
    bit_transfered<=9'b0;
  else if(main_state==START)
    bit_transfered<=9'b0_0000_0001;
  else if(sck_count==0)
    bit_transfered<={bit_transfered[7:0],bit_transfered[8]};


always @(posedge clk)
  if(sck_count==0)
    data_received<={data_received[6:0],sdo_in};

always @(posedge clk)
  if(main_state==DATA && bit_transfered[7]==1 && read_flag==1 && sck_count==1)
    rd_data_valid<=1;
  else 
    rd_data_valid<=0;

always @(posedge clk)
  if(main_state==DATA && bit_transfered[7]==1 && read_flag==1 && sck_count==1)
    rd_data<=data_received;

always @(posedge clk)
  if(main_state==IDLE)
     busy<=0;
  else
     busy<=1;

endmodule 





   











 

          

⌨️ 快捷键说明

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