Files

465 lines
20 KiB
Verilog

`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