利用线性序列机根据时序图和手册中的输出值的对应关系。
DAC这边的知识基本相同。
在验证的时候发现了问题,反推仿真的时候发现了,子啊lsm_cnt线性序列机计数的33到了之后还有一位,发现是set_en的问题,因为set_en使能才能计数。
这边是正确的波形图和代码对应
always @(posedge clk or negedge reset_n)
if(!reset_n)
set_en <= 1'd0;
else if(set_go)
set_en <= 1'd1;
else if((lsm_cnt == 33) && (div_cnt == MCNT_DIV_CNT))
set_en <= 1'd0;
else
set_en <= set_en;
always @(posedge clk or negedge reset_n)
if(!reset_n)
div_cnt <= 0;
else if(set_en) begin
if(div_cnt == MCNT_DIV_CNT)
div_cnt <= 0;
else
div_cnt <= div_cnt + 1'd1;
end
else
div_cnt <= 0;
always @(posedge clk or negedge reset_n)
if(!reset_n)
lsm_cnt <= 6'd0;
else if(div_cnt == MCNT_DIV_CNT)begin
if(lsm_cnt == 6'd33)
lsm_cnt <= 6'd0;
else
lsm_cnt <= lsm_cnt + 1'd1;
end
else
lsm_cnt <= lsm_cnt;
always @(posedge clk or negedge reset_n)
if(!reset_n)
set_done <= 0;
else if((lsm_cnt == 33) && (div_cnt == MCNT_DIV_CNT))
set_done <= 1'd1;
else
set_done <= 1'd0;
这边看到在div_cnt和lsm_cnt计数满,将set_done信号触发,触发转换结束信号。
同时通过计数满的信号,拉低set_en使能,从而停止计数
我第一次写的时候,是通过set_done信号来拉低set_en信号
always @(posedge clk or negedge reset_n)
if(!reset_n)
set_en <= 1'd0;
else if(set_go)
set_en <= 1'd1;
else if(set_done)
set_en <= 1'd0;
else
set_en <= set_en;
这边的仿真图就出现了问题,因为set_done信号是一拍,而set_en信号在下一个clk时钟上升沿才拉低。
也就导致在lsm_cnt到33计满之后,set_en还是高电平,所以继续计数,div_cnt因为没计满,所以多了一个lsm_cnt计数。
间接导致
0: begin dac_sclk <= 1'd1; dac_cs_n <= 1'd0; dac_din <= r_dac_data[15];
这个函数,将r_dac_data[15]的值计入了dac_din当中,这些都是set_done之后的,所以不应该产生。会导致最后接收模拟信号输出的时候的时序混乱
标签:cnt,set,转换,FPGA,DAC,lsm,计数,en,done From: https://www.cnblogs.com/cjl520/p/18064521