Created
September 30, 2022 07:28
-
-
Save tzechienchu/6eb5ebb8e237d7888ef13970bd675843 to your computer and use it in GitHub Desktop.
Analog Device DAC Driver use Verilog
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Analog Device DAC Driver | |
module ad_dac( | |
clk, | |
rst, | |
send, | |
valid, | |
tx_value, | |
channel, | |
command, | |
rx_value, | |
rx_valid, | |
sclk, | |
sync, | |
to_sdi, | |
from_sdo | |
); | |
input wire clk; | |
input wire rst; | |
input wire valid; | |
input wire send; | |
input wire[15:0] tx_value; | |
output wire[23:0] rx_value; | |
input wire[3:0] channel; | |
input wire[3:0] command; | |
output wire sclk; | |
output wire sync; | |
output wire to_sdi; | |
input wire from_sdo; | |
output wire rx_valid; | |
localparam IDLE = 3'b000, | |
WAIT_START_0 = 3'b001, | |
WAIT_START_1 = 3'b011, | |
TRANSFER = 3'b111, | |
WAIT_END_0 = 3'b110, | |
WAIT_END_1 = 3'b100; | |
reg[2:0] state_reg, state_next; | |
reg[1:0] sck_counter, sck_counter_next; | |
reg[4:0] bit_counter, bit_counter_next; | |
reg[23:0] temp_reg, temp_next; | |
reg[23:0] channel_data, channel_data_next; | |
reg[23:0] rx_value_reg, rx_value_next; | |
reg to_sdi_q, to_sdi_d; | |
reg valid_q, valid_d; | |
wire busy; | |
assign to_sdi = to_sdi_q; | |
assign sclk = (sck_counter[1]) & (state_reg == TRANSFER); | |
assign rx_valid = valid_q; | |
assign busy = (state_reg != IDLE); | |
assign sync = !busy; | |
assign rx_value = rx_value_reg; | |
always @(valid) begin | |
temp_next = temp_reg; | |
if (valid) begin | |
temp_next <= {command[3:0], channel[3:0], tx_value[15:0]}; | |
end | |
end | |
always @(*) begin | |
state_next = state_reg; | |
case(state_reg) | |
IDLE: begin | |
if (send == 1'b1) begin | |
state_next = WAIT_START_0; | |
end | |
end | |
WAIT_START_0: begin | |
state_next = WAIT_START_1; | |
end | |
WAIT_START_1: begin | |
state_next = TRANSFER; | |
end | |
TRANSFER: begin | |
if (sck_counter == {2'b11}) begin | |
if (bit_counter == 5'b1_0111) begin | |
state_next = WAIT_END_0; | |
end | |
end | |
end | |
WAIT_END_0: begin | |
state_next = WAIT_END_1; | |
end | |
WAIT_END_1: begin | |
state_next = IDLE; | |
end | |
endcase | |
end | |
always @(posedge clk) begin | |
if (rst) begin | |
state_next <= 0; | |
end else begin | |
state_reg <= state_next; | |
end | |
end | |
always @(*) begin | |
valid_d = valid_q; | |
sck_counter_next = sck_counter; | |
bit_counter_next = bit_counter; | |
channel_data_next = channel_data; | |
rx_value_next = rx_value_reg; | |
case(state_reg) | |
IDLE: begin | |
valid_d = 1'b0; | |
sck_counter_next = 4'b0; | |
bit_counter_next = 5'b0; | |
if (send == 1'b1) begin | |
channel_data_next = temp_reg; | |
end | |
end | |
TRANSFER: begin | |
sck_counter_next = sck_counter + 1'b1; | |
if (sck_counter == 2'b00) begin | |
to_sdi_d = channel_data[23]; | |
end else if (sck_counter == 2'b01) begin | |
channel_data_next = {channel_data[22:0], from_sdo}; | |
end else if (sck_counter == 2'b11) begin | |
bit_counter_next = bit_counter + 1'b1; | |
if (bit_counter == 5'b1_0111) begin | |
rx_value_next = channel_data; | |
valid_d = 1'b1; | |
end | |
end | |
end | |
WAIT_END_1: begin | |
valid_d = 1'b0; | |
end | |
endcase | |
end | |
always @(posedge clk) begin | |
if (rst) begin | |
temp_next <= 0; | |
sck_counter_next <= 0; | |
bit_counter_next <= 0; | |
rx_value_next <= 0; | |
channel_data_next <= 0; | |
to_sdi_d <= 0; | |
valid_d <= 0; | |
end else begin | |
temp_reg <= temp_next; | |
sck_counter <= sck_counter_next; | |
bit_counter <= bit_counter_next; | |
rx_value_reg <= rx_value_next; | |
channel_data <= channel_data_next; | |
to_sdi_q <= to_sdi_d; | |
valid_q <= valid_d; | |
end | |
end | |
endmodule |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment