`timescale 1 ns / 1 ps module dac80508_controller ( input wire clk, // 100MHz时钟 input wire rst_n, // 复位信号(低有效) (*mark_debug="true"*)input wire stim_en, (*mark_debug="true"*)input wire imp_test_en , (*mark_debug="true"*)input wire [23:0] stim_data , (*mark_debug="true"*)input wire stim_data_en , (*mark_debug="true"*)output reg cs_n, // 片选信号 (*mark_debug="true"*)output reg sclk, // 串行时钟(分频后) (*mark_debug="true"*)output reg sdi, // 数据输出 (*mark_debug="true"*)output reg [3:0] state , //input wire [8*16-1:0] data_in, //数据输入 (*mark_debug="true"*)input wire [23:0] data_in , (*mark_debug="true"*)input wire imp_fifo_rd_en // input wire imp_data_en , // (*mark_debug="true"*)input wire phase_en ); parameter IDLE = 'b0001; parameter BROARDCAST_SET = 'b0010; parameter DAC80508_MID_INITIAL = 'b0011; parameter GAIN_SET_SINE = 'b0100; parameter WAIT_SEND_DATA = 'b0101; parameter WAIT_SEND_DATACS = 'b0110; parameter SEND_DATA = 'b0111; parameter SEND_DATA_CS = 'b1000; parameter SEND_DATA_CS1 = 'b1001; parameter DELAY = 'b1010; // (*mark_debug="true"*)reg [3:0] state; //reg [15:0] shift_reg ; //reg [4:0] bit_cnt ; // (*mark_debug="true"*)wire [2:0] channel ; // reg [6:0] cnt_1us ; // reg phase_en_dly ; (*mark_debug="true"*)reg [23:0] asyc_set ; (*mark_debug="true"*)reg [4:0] cmd_bit_count ; // (*mark_debug="true"*)reg start ; // (*mark_debug="true"*)reg start_dly ; // (*mark_debug="true"*)wire [15:0] data_in_o[0:7] ; // (*mark_debug="true"*)wire [23:0] data_in_c[0:7] ; (*mark_debug="true"*)reg [7:0] stim_wait_cnt ; (*mark_debug="true"*)reg [7:0] delay_wait_cnt ; (*mark_debug="true"*)wire [23:0] stim_data_dout ; (*mark_debug="true"*)wire fifo_empty ; (*mark_debug="true"*)reg fifo_rd_en ; // (*mark_debug="true"*)reg [15:0] imp_data_cnt ; // (*mark_debug="true"*)reg imp_data_pls ; // (*mark_debug="true"*)reg [2:0] channel_tmp ; // (*mark_debug="true"*)reg imp_data_start; (*mark_debug="true"*)wire [23:0] dac0_mid ; wire [23:0] dac1_mid ; wire [23:0] dac2_mid ; wire [23:0] dac3_mid ; wire [23:0] dac4_mid ; wire [23:0] dac5_mid ; wire [23:0] dac6_mid ; wire [23:0] dac7_mid ; (*mark_debug="true"*)reg [9:0] dac_mid_cnt ; wire [23:0] gain_set ; reg [5:0] gain_set_cnt ; //assign data_in_c[23:0][0:7]={4'b0,1'b1,channel[2:0],data_in_o[channel]}; assign dac0_mid[23:0]=24'h88000; assign dac1_mid[23:0]=24'h98000; assign dac2_mid[23:0]=24'ha8000; assign dac3_mid[23:0]=24'hb8000; assign dac4_mid[23:0]=24'hc8000; assign dac5_mid[23:0]=24'hd8000; assign dac6_mid[23:0]=24'he8000; assign dac7_mid[23:0]=24'hf8000; assign gain_set[23:0]=24'h401ff ; // assign channel[2:0] = channel_tmp[2:0]-1 ; // genvar i; // generate // for(i=0;i<8;i=i+1) begin : unpack //正弦波分配 // assign data_in_o[i] = data_in[16*i+15 : 16*i]; // end // endgenerate // genvar j; // generate // for(j=0;j<8;j=j+1) begin : unpack1 //正弦波前面加上控制 // assign data_in_c[j] = {4'b0,1'b1,channel[2:0],data_in_o[j]}; // end // endgenerate // always @(posedge clk or negedge rst_n) begin //阻抗测试加上phase_en // if (!rst_n) begin // phase_en_dly <= 1'b0; // end else begin // phase_en_dly <= phase_en ; // end // end // always @(posedge clk or negedge rst_n) begin //阻抗测试开始 // if (!rst_n) begin // start <= 1'b0; // end else if(imp_test_en==1'b1)begin // if((phase_en==1'b1)&&(phase_en_dly==1'b0))begin // start <= 1'b1; // end // else begin // start <= start ; // end // end else begin // start <= 1'b0; // end // end // always @(posedge clk or negedge rst_n) begin //阻抗测试开始打拍 // if (!rst_n) begin // start_dly <= 1'b0; // end else begin // start_dly <= start; // end // end // always @(posedge clk or negedge rst_n) begin //阻抗测试计时 // if (!rst_n) begin // cnt_1us[6:0] <= 7'b0; // end else if(start==1'b1)begin //start==1'b1 // if(cnt_1us[6:0]==7'd99) // cnt_1us[6:0] <= 7'b0; // else // cnt_1us[6:0] <= cnt_1us[6:0]+1'b1; // end else begin // cnt_1us[6:0] <= 7'b0 ; // end // end // always @(posedge clk or negedge rst_n) begin //阻抗测试通道对齐 // if (!rst_n) begin // imp_data_start <= 1'b0; // end else if(imp_test_en)begin // if(imp_data_en==1'b1)begin // imp_data_start <= 1'b1; // end else begin // imp_data_start <= imp_data_start; // end // end else begin // imp_data_start <= 1'b0; // end // end // always @(posedge clk or negedge rst_n) begin //阻抗测试通道对齐 // if (!rst_n) begin // imp_data_cnt[15:0] <= 16'b0; // end else if(imp_data_start==1'b1)begin // if(imp_data_en==1'b1)begin // imp_data_cnt[15:0] <= 16'b0; // end else if(imp_data_cnt[15:0]==16'd3000)begin // imp_data_cnt[15:0] <= imp_data_cnt[15:0] ; // end else begin // imp_data_cnt[15:0] <= imp_data_cnt[15:0] + 1'b1 ; // end // end else begin // imp_data_cnt[15:0] <= 16'b0; // end // end // always @(posedge clk or negedge rst_n) begin //阻抗测试通道对齐 // if (!rst_n) begin // imp_data_pls <= 1'b0; // channel_tmp[2:0] <= 3'b0; // end else if(imp_test_en==1'b1)begin // if((imp_data_cnt[15:0]==16'd1)||(imp_data_cnt[15:0]==16'd301)||(imp_data_cnt[15:0]==16'd601)||(imp_data_cnt[15:0]==16'd901)||(imp_data_cnt[15:0]==16'd1201)||(imp_data_cnt[15:0]==16'd1501)||(imp_data_cnt[15:0]==16'd1801)||(imp_data_cnt[15:0]==16'd2101))begin // imp_data_pls <= 1'b1; // channel_tmp[2:0] <= channel_tmp[2:0]+1'b1; // end else begin // imp_data_pls <= 1'b0; // channel_tmp[2:0] <= channel_tmp[2:0]; // end // end else begin // imp_data_pls <= 1'b0; // channel_tmp[2:0] <= 3'b0; // end // end // always @(posedge clk or negedge rst_n) begin //刺激等待时间 // if (!rst_n) begin // stim_wait_cnt[7:0] <= 8'b0; // end else if(imp_test_en==1'b1)begin // stim_wait_cnt[7:0] <= 8'b0; // end else begin // if(stim_data_en==1'b1)//stim_en==1'b1 // stim_wait_cnt[7:0] <= 8'b0; // else if(stim_wait_cnt[7:0]==8'd199) // stim_wait_cnt[7:0] <= stim_wait_cnt[7:0] ; // else // stim_wait_cnt[7:0] <= stim_wait_cnt[7:0]+1'b1 ; // end // end always @(posedge clk or negedge rst_n) begin //刺激等待时间 if (!rst_n) begin stim_wait_cnt[7:0] <= 8'b0; end else if((fifo_empty==1'b0)&&(state == WAIT_SEND_DATA))begin stim_wait_cnt[7:0] <= stim_wait_cnt[7:0]+1'b1; end else begin stim_wait_cnt[7:0] <= 8'b0; end end always @(posedge clk or negedge rst_n) begin //刺激等待时间 if (!rst_n) begin stim_wait_cnt[7:0] <= 8'b0; end else if((fifo_empty==1'b0)&&(state == WAIT_SEND_DATA))begin stim_wait_cnt[7:0] <= stim_wait_cnt[7:0]+1'b1; end else begin stim_wait_cnt[7:0] <= 8'b0; end end always @(posedge clk or negedge rst_n) begin //刺激等待时间 if (!rst_n) begin fifo_rd_en <= 1'b0; end else if(imp_test_en==1'b1)begin fifo_rd_en <= 1'b0; end else if((fifo_empty==1'b0)&&(state == WAIT_SEND_DATA)&&(stim_wait_cnt[7:0]==8'd3))begin fifo_rd_en <= 1'b1; end else begin fifo_rd_en <= 1'b0; end end // 主控制逻辑 always @(posedge clk or negedge rst_n) begin if (!rst_n) begin state <= IDLE; sclk <= 0; cs_n <= 1; //bit_cnt <= 5'b0 ; //shift_reg[15:0] <= 16'b0; asyc_set[23:0] <= 24'h20000;//set broadcast sdi <= 0 ; cmd_bit_count[4:0] <= 5'd0; dac_mid_cnt[9:0] <= 10'b0 ; gain_set_cnt[5:0] <= 6'd0 ; delay_wait_cnt[7:0] <= 8'b0 ; end else begin case (state) IDLE: begin //进入IDLE模式 cs_n <= 0; cmd_bit_count[4:0] <= 5'd23; state <= BROARDCAST_SET; delay_wait_cnt[7:0] <= 8'b0 ; end BROARDCAST_SET:begin //进入广播模式 sclk <= ~sclk ; if(cmd_bit_count>0)begin sdi <= asyc_set[cmd_bit_count]; if(sclk)cmd_bit_count<=cmd_bit_count-1 ; end else if(sclk) begin cs_n <= 0; //cs_n <= 1; sclk <= ~sclk; sdi <= asyc_set[0]; state <= DAC80508_MID_INITIAL ;//WAIT_SEND_DATA ; end end DAC80508_MID_INITIAL:begin //初始值每个通道设置为1.25V if(dac_mid_cnt[9:0]==10'd1022)begin dac_mid_cnt[9:0] <= 10'd0 ; state <= GAIN_SET_SINE; end else begin dac_mid_cnt[9:0] <= dac_mid_cnt[9:0] + 1'b1 ; state <= state; end if((dac_mid_cnt[9:0]>=10'd1)&&(dac_mid_cnt[9:0]<=10'd52)||(dac_mid_cnt[9:0]>=10'd57)&&(dac_mid_cnt[9:0]<=10'd108)||(dac_mid_cnt[9:0]>=10'd113)&&(dac_mid_cnt[9:0]<=10'd164)||(dac_mid_cnt[9:0]>=10'd169)&&(dac_mid_cnt[9:0]<=10'd220)|| (dac_mid_cnt[9:0]>=10'd225)&&(dac_mid_cnt[9:0]<=10'd276)||(dac_mid_cnt[9:0]>=10'd281)&&(dac_mid_cnt[9:0]<=10'd332)||(dac_mid_cnt[9:0]>=10'd337)&&(dac_mid_cnt[9:0]<=10'd388)||(dac_mid_cnt[9:0]>=10'd393)&&(dac_mid_cnt[9:0]<=10'd444)) cs_n <= 0 ; else cs_n <= 1 ; if((dac_mid_cnt[9:0]>=10'd3)&&(dac_mid_cnt[9:0]<=10'd50)||(dac_mid_cnt[9:0]>=10'd59)&&(dac_mid_cnt[9:0]<=10'd106)||(dac_mid_cnt[9:0]>=10'd115)&&(dac_mid_cnt[9:0]<=10'd162)||(dac_mid_cnt[9:0]>=10'd171)&&(dac_mid_cnt[9:0]<=10'd218)|| (dac_mid_cnt[9:0]>=10'd227)&&(dac_mid_cnt[9:0]<=10'd274)||(dac_mid_cnt[9:0]>=10'd283)&&(dac_mid_cnt[9:0]<=10'd330)||(dac_mid_cnt[9:0]>=10'd339)&&(dac_mid_cnt[9:0]<=10'd386)||(dac_mid_cnt[9:0]>=10'd395)&&(dac_mid_cnt[9:0]<=10'd442)) sclk <= ~sclk ; else sclk <= 0 ; if((dac_mid_cnt[9:0]==10'd0)||(dac_mid_cnt[9:0]==10'd56)||(dac_mid_cnt[9:0]==10'd112)||(dac_mid_cnt[9:0]==10'd168)||(dac_mid_cnt[9:0]==10'd224)||(dac_mid_cnt[9:0]==10'd280)||(dac_mid_cnt[9:0]==10'd336)||(dac_mid_cnt[9:0]==10'd392))begin cmd_bit_count[4:0] <= 5'd23; sdi <= 1'b1 ; end else if(cmd_bit_count[4:0]>0)begin if(sclk)cmd_bit_count <= cmd_bit_count-1 ; if((dac_mid_cnt[9:0]>=10'd3)&&(dac_mid_cnt[9:0]<=10'd50)) sdi <= dac0_mid[cmd_bit_count]; else if((dac_mid_cnt[9:0]>=10'd59)&&(dac_mid_cnt[9:0]<=10'd106)) sdi <= dac1_mid[cmd_bit_count]; else if((dac_mid_cnt[9:0]>=10'd115)&&(dac_mid_cnt[9:0]<=10'd162)) sdi <= dac2_mid[cmd_bit_count]; else if((dac_mid_cnt[9:0]>=10'd171)&&(dac_mid_cnt[9:0]<=10'd218)) sdi <= dac3_mid[cmd_bit_count]; else if((dac_mid_cnt[9:0]>=10'd227)&&(dac_mid_cnt[9:0]<=10'd274)) sdi <= dac4_mid[cmd_bit_count]; else if((dac_mid_cnt[9:0]>=10'd283)&&(dac_mid_cnt[9:0]<=10'd330)) sdi <= dac5_mid[cmd_bit_count]; else if((dac_mid_cnt[9:0]>=10'd339)&&(dac_mid_cnt[9:0]<=10'd386)) sdi <= dac6_mid[cmd_bit_count]; else if((dac_mid_cnt[9:0]>=10'd395)&&(dac_mid_cnt[9:0]<=10'd442)) sdi <= dac7_mid[cmd_bit_count]; else sdi <= 1'b0 ; end else begin cmd_bit_count[4:0] <= cmd_bit_count[4:0] ; sdi <= 1'b0 ;//sdi <= 1'b1 end end GAIN_SET_SINE:begin //增加GAIN,先除以2,再乘以2 dac_mid_cnt[9:0] <= 10'b0 ; if(gain_set_cnt[5:0]==6'd55)begin gain_set_cnt[5:0] <= 6'd0 ; state <= WAIT_SEND_DATA; end else begin gain_set_cnt[5:0] <= gain_set_cnt[5:0] + 1'b1 ; state <= state; end if((gain_set_cnt[5:0]>=6'd1)&&(gain_set_cnt[5:0]<=6'd52)) cs_n <= 0 ; else cs_n <= 1 ; if((gain_set_cnt[5:0]>=6'd3)&&(gain_set_cnt[5:0]<=6'd50)) sclk <= ~sclk ; else sclk <= 0 ; if(gain_set_cnt[5:0]==6'd0)begin cmd_bit_count[4:0] <= 5'd23; sdi <= 1'b1 ; end else if(cmd_bit_count[4:0]>0)begin if(sclk)cmd_bit_count <= cmd_bit_count-1 ; if((gain_set_cnt[5:0]>=6'd3)&&(gain_set_cnt[5:0]<=6'd50)) sdi <= gain_set[cmd_bit_count]; else sdi <= 1'b0 ; end else begin cmd_bit_count[4:0] <= cmd_bit_count[4:0] ; sdi <= 1'b1 ; end end WAIT_SEND_DATA:begin //等待发送数据 dac_mid_cnt[9:0] <= 10'b0 ; // if ((stim_en==1'b0)&&(imp_test_en==1'b0))begin // state <= DAC80508_MID_INITIAL ; // cs_n <= 1; // 使能片选 // sdi <= 1'b0 ;//new add // delay_wait_cnt[7:0] <= 8'b0 ; if ( fifo_rd_en || imp_fifo_rd_en)begin //((start==1'b1)&&(start_dly==1'b0))imp_data_pls stim_data_en,stim_en imp_data_en state <= WAIT_SEND_DATACS; cs_n <= 1; // 使能片选 sdi <= 1'b0 ;//new add delay_wait_cnt[7:0] <= 8'b0 ; //cmd_bit_count[4:0] <= 5'd23; end end WAIT_SEND_DATACS:begin //等待CS_n dac_mid_cnt[9:0] <= 10'b0 ; // if ((stim_en==1'b0)&&(imp_test_en==1'b0))begin // state <= DAC80508_MID_INITIAL ; // cs_n <= 1; // 使能片选 // sdi <= 1'b0 ;//new add // delay_wait_cnt[7:0] <= 8'b0 ; //end else begin state <= SEND_DATA; cs_n <= 0; // 使能片选 cmd_bit_count[4:0] <= 5'd23; // end end SEND_DATA:begin //发送数据 dac_mid_cnt[9:0] <= 10'b0 ; sclk <= ~sclk ; // if ((stim_en==1'b0)&&(imp_test_en==1'b0))begin // state <= DAC80508_MID_INITIAL ; // cs_n <= 1; // 使能片选 // sdi <= 1'b0 ;//new add // delay_wait_cnt[7:0] <= 8'b0 ; if(cmd_bit_count>0)begin cs_n <= 0; sdi <= imp_test_en?data_in[cmd_bit_count]:stim_data_dout[cmd_bit_count];//data_in_c[channel][cmd_bit_count]:stim_data_dout[cmd_bit_count]; if(sclk)cmd_bit_count<=cmd_bit_count-1 ; end else if((cmd_bit_count==0)&&(!sclk))begin //新增加,主要防止最后一个数据输出错误的问题 cs_n <= 0; sdi <= imp_test_en?data_in[0]:stim_data_dout[0];//data_in_o[channel][0]:stim_data_dout[0]; //if(sclk)cmd_bit_count<=cmd_bit_count-1 ; end else if(sclk) begin cs_n <= 0; sclk <= ~sclk; //sdi <= imp_test_en?data_in_o[channel][0]:stim_data[0];//之前用这个有问题,正弦波输出有点毛刺 state <= SEND_DATA_CS ; end end SEND_DATA_CS:begin //等待CS // dac_mid_cnt[9:0] <= 10'b0 ; // if ((stim_en==1'b0)&&(imp_test_en==1'b0))begin // state <= DAC80508_MID_INITIAL ; // cs_n <= 1; // 使能片选 // sdi <= 1'b0 ;//new add // delay_wait_cnt[7:0] <= 8'b0 ; //end else begin cs_n <= 0; state <= SEND_DATA_CS1 ; sdi <= 0 ; //end end SEND_DATA_CS1:begin //等待CS // dac_mid_cnt[9:0] <= 10'b0 ; // if ((stim_en==1'b0)&&(imp_test_en==1'b0))begin // state <= DAC80508_MID_INITIAL ; // cs_n <= 1; // 使能片选 // sdi <= 1'b0 ;//new add // delay_wait_cnt[7:0] <= 8'b0 ; // end else begin cs_n <= 1; state <= DELAY ; // end end DELAY: begin //1us或2us等待时间 dac_mid_cnt[9:0] <= 10'b0 ; delay_wait_cnt[7:0] <= delay_wait_cnt[7:0] + 1'b1 ; // if ((stim_en==1'b0)&&(imp_test_en==1'b0))begin // state <= DAC80508_MID_INITIAL ; // cs_n <= 1; // 使能片选 // sdi <= 1'b0 ;//new add if (imp_test_en==1'b1)begin if(delay_wait_cnt[7:0]==8'd99)begin//cnt_1us[6:0]==7'd99 state <= WAIT_SEND_DATA;//WAIT_SEND_DATACS; // 1μs延时 end else begin state <= state ; end end else if(delay_wait_cnt[7:0]==8'd199)begin // if(stim_wait_cnt[7:0]==8'd199) state <= WAIT_SEND_DATA ; end end endcase end end fifo_generator_3 u_fifo_generator_3( .full( ), .din(stim_data[23:0]), .wr_en(stim_data_en), .empty(fifo_empty ), .dout(stim_data_dout[23:0]), .rd_en(fifo_rd_en), .rst(~rst_n), .wr_clk(clk), .rd_clk(clk) //clk_100m ); endmodule