时序图
上图为LDAC控制的时序图,根据时序图我们把输出定为:
output reg dac_clk,
output reg dac_sda,
output reg dac_load,
output reg dac_ldac
把A1 A0 RNG D7~D0 作为输入,令其为cmd[10:0],则输入为:
input wire clk,
input wire rst_n,
input wire [10:0] cmd,
整体代码
module dac_drive (
input wire clk,
input wire rst_n,
input wire [10:0] cmd,
output reg dac_clk,
output reg dac_sda,
output reg dac_load,
output reg dac_ldac
);
reg [9:0] cnt;
localparam T = 25;
/*************计数器*************/
always @ (posedge clk) begin
if (rst_n == 0)
cnt <= 0;
else if(cnt < 601)
cnt <= cnt + 1'b1;
else
cnt <= 601;
end
always @ (posedge clk) begin
if (rst_n == 0) begin
dac_clk <= 0;
dac_sda <= 0;
dac_load <= 1;
dac_ldac <= 1;
end
else
case (cnt)
0 : begin dac_clk <= 0; dac_sda <= 0; dac_load <= 1;
dac_ldac <= 1;end
1 : begin dac_clk <= 1; dac_sda <= cmd[0];end
1 + T * 1 : begin dac_clk <= 0; end
1 + T * 2 : begin dac_clk <= 1; dac_sda <= cmd[1];end
1 + T * 3 : begin dac_clk <= 0; end
1 + T * 4 : begin dac_clk <= 1; dac_sda <= cmd[2];end
1 + T * 5 : begin dac_clk <= 0; end
1 + T * 6 : begin dac_clk <= 1; dac_sda <= cmd[3];end
1 + T * 7 : begin dac_clk <= 0; end
1 + T * 8 : begin dac_clk <= 1; dac_sda <= cmd[4];end
1 + T * 9 : begin dac_clk <= 0; end
1 + T * 10 : begin dac_clk <= 1; dac_sda <= cmd[5];end
1 + T * 11 : begin dac_clk <= 0; end
1 + T * 12 : begin dac_clk <= 1; dac_sda <= cmd[6];end
1 + T * 13 : begin dac_clk <= 0; end
1 + T * 14 : begin dac_clk <= 1; dac_sda <= cmd[7];end
1 + T * 15 : begin dac_clk <= 0; end
1 + T * 16 : begin dac_clk <= 1; dac_sda <= cmd[8];end
1 + T * 17 : begin dac_clk <= 0; end
1 + T * 18 : begin dac_clk <= 1; dac_sda <= cmd[9];end
1 + T * 19 : begin dac_clk <= 0; end
1 + T * 20 : begin dac_clk <= 1; dac_sda <= cmd[10];end
1 + T * 21 : begin dac_clk <= 0; end
1 + T * 22 : begin dac_clk <= 1; dac_sda <= 0; dac_load <= 0;end
1 + T * 23 : begin dac_clk <= 0; dac_load <= 1; dac_ldac <= 0;end
1 + T * 24 : begin dac_clk <= 1; dac_ldac <= 1;end
default : ;
endcase
end
endmodule
代码采用线性序列机的方式,根据时序图完成代码。
仿真代码
`timescale 1ns/1ps
module dac_drive_tb;
reg clk;
reg rst_n;
reg [10:0] cmd;
wire dac_clk;
wire dac_sda;
wire dac_load;
wire dac_ldac;
dac_drive dac_drive_inst(
.clk (clk),
.rst_n (rst_n),
.cmd (cmd),
.dac_clk (dac_clk),
.dac_sda (dac_sda),
.dac_load (dac_load),
.dac_ldac (dac_ldac)
);
initial clk = 1;
always #10 clk = ~clk; //50Mhz的晶振
initial begin
rst_n = 0;
#201
rst_n = 1;
cmd = 11'b00_1_10101100; //前两位为选择DAC的端口 第三位为RNG 后八位是D7~D0
repeat (700) //因为计数601 所以跑700个足够
@ (posedge clk);
#200
$stop;
end
endmodule
clk开始为低 data开始随机,这里设置为0(low) LOAD为高, LDAC为高 。
其中A1A0决定用哪个DAC,RNG代表倍数 范围是1-2倍(RNG=0为1倍,RNG=1为2倍) D7-D0为数据位。
仿真图
最后在modolsim中进行仿真,结果如下图: