利用線性序列機根據時序圖和手冊中的輸出值的對應關係。
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之後的,所以不應該產生。會導致最後接收模擬訊號輸出的時候的時序混亂