config_dac.v.bak

来自「Verilog实现 spi接口的FPGA实现 通过仿真」· BAK 代码 · 共 205 行

BAK
205
字号
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 + =
减小字号Ctrl + -
显示快捷键?