尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

AD7606模数转换器——(二)FPGA程序设计

AD7606模数转换器——(二)FPGA程序设计 本部分主要介绍FPGA的设计通过状态机实现相应的功能。// AD7606 八通道并行接口控制器 // // 时序概览上电复位 - CONVST 低脉冲 - 等待 BUSY 上升、下降 // - 依次读取 8 个 16 位通道 - frame_done - 采样间隔 // // 参数的单位均为 clk 周期且必须不小于 1。 // 请依据所用 AD7606 型号的数据手册、系统时钟与板级时序进行复核。 //---------------------------------------------------------------------------------------- // File name: ad7606_parallel_fsm // Created by: 天使鲨 // Created date: 2026年8月30日17:09:02 // Version: V1.0 // Descriptions: ad7606驱动模块 // //--------------------------------------------------------------------------------------- module ad7606_parallel_fsm #( parameter integer SAMPLE_PERIOD_CYCLES 5000, parameter integer CONVST_LOW_CYCLES 2, parameter integer RD_LOW_CYCLES 2, parameter integer RD_HIGH_CYCLES 2, parameter integer RESET_HOLD_CYCLES 8, parameter [2:0] OS_VALUE 3b000 ) ( input clk, input rst_n, // 在空闲状态拉高可启动一次采样保持为高则按 SAMPLE_PERIOD_CYCLES 连续采样。 input start, input busy, input [15:0] db, output cs_n, output rd_n, output [2:0] os, output reset, output convst_n, output reg [7:0] channel_valid, output reg frame_done, output reg [15:0] last_sample, output reg [15:0] ch1, output reg [15:0] ch2, output reg [15:0] ch3, output reg [15:0] ch4, output reg [15:0] ch5, output reg [15:0] ch6, output reg [15:0] ch7, output reg [15:0] ch8 ); localparam [3:0] ST_HW_RESET 4d0; localparam [3:0] ST_IDLE 4d1; localparam [3:0] ST_CONVST_LOW 4d2; localparam [3:0] ST_WAIT_BUSY_HIGH 4d3; localparam [3:0] ST_WAIT_BUSY_LOW 4d4; localparam [3:0] ST_READ_LOW 4d5; localparam [3:0] ST_READ_HIGH 4d6; localparam [3:0] ST_REPORT 4d7; localparam [3:0] ST_SAMPLE_GAP 4d8; reg [3:0] state; reg [31:0] phase_count; reg [31:0] sample_count; reg [2:0] channel_index; reg busy_meta; reg busy_sync; // 异步 BUSY 信号先经过两级同步避免直接进入状态机。 always (posedge clk or negedge rst_n) begin if (!rst_n) begin busy_meta 1b0; busy_sync 1b0; end else begin busy_meta busy; busy_sync busy_meta; end end // 引脚直接由状态译码读期间 CS 与 RD 同时有效。 assign convst_n (state ST_CONVST_LOW) ? 1b0 : 1b1; assign rd_n (state ST_READ_LOW) ? 1b0 : 1b1; assign cs_n rd_n; assign reset (state ST_HW_RESET) ? 1b1 : 1b0; assign os OS_VALUE; // 控制状态、各阶段计时以及通道索引。 always (posedge clk or negedge rst_n) begin if (!rst_n) begin state ST_HW_RESET; phase_count 32d0; sample_count 32d0; channel_index 3d0; end else begin case (state) ST_HW_RESET: begin if (phase_count RESET_HOLD_CYCLES - 1) begin phase_count 32d0; state ST_IDLE; end else begin phase_count phase_count 1b1; end end ST_IDLE: begin phase_count 32d0; sample_count 32d0; channel_index 3d0; if (start) state ST_CONVST_LOW; end ST_CONVST_LOW: begin if (phase_count CONVST_LOW_CYCLES - 1) begin phase_count 32d0; state ST_WAIT_BUSY_HIGH; end else begin phase_count phase_count 1b1; end end // 先确认 BUSY 已经拉高再等待它拉低避免误读上一次转换。 ST_WAIT_BUSY_HIGH: begin if (busy_sync) state ST_WAIT_BUSY_LOW; end ST_WAIT_BUSY_LOW: begin if (!busy_sync) begin phase_count 32d0; channel_index 3d0; state ST_READ_LOW; end end ST_READ_LOW: begin if (phase_count RD_LOW_CYCLES - 1) begin phase_count 32d0; state ST_READ_HIGH; end else begin phase_count phase_count 1b1; end end ST_READ_HIGH: begin if (phase_count RD_HIGH_CYCLES - 1) begin phase_count 32d0; if (channel_index 3d7) begin state ST_REPORT; end else begin channel_index channel_index 1b1; state ST_READ_LOW; end end else begin phase_count phase_count 1b1; end end ST_REPORT: begin sample_count 32d0; if (start) state ST_SAMPLE_GAP; else state ST_IDLE; end ST_SAMPLE_GAP: begin if (!start) begin state ST_IDLE; end else if (sample_count SAMPLE_PERIOD_CYCLES - 1) begin sample_count 32d0; phase_count 32d0; channel_index 3d0; state ST_CONVST_LOW; end else begin sample_count sample_count 1b1; end end default: begin state ST_HW_RESET; phase_count 32d0; sample_count 32d0; channel_index 3d0; end endcase end end // 在 RD 低电平的最后一个时钟沿锁存并行数据。 // channel_valid 和 frame_done 均为单时钟周期脉冲。 always (posedge clk or negedge rst_n) begin if (!rst_n) begin channel_valid 8d0; frame_done 1b0; last_sample 16d0; ch1 16d0; ch2 16d0; ch3 16d0; ch4 16d0; ch5 16d0; ch6 16d0; ch7 16d0; ch8 16d0; end else begin channel_valid 8d0; frame_done 1b0; if ((state ST_READ_LOW) (phase_count RD_LOW_CYCLES - 1)) begin last_sample db; case (channel_index) 3d0: begin ch1 db; channel_valid 8b0000_0001; end 3d1: begin ch2 db; channel_valid 8b0000_0010; end 3d2: begin ch3 db; channel_valid 8b0000_0100; end 3d3: begin ch4 db; channel_valid 8b0000_1000; end 3d4: begin ch5 db; channel_valid 8b0001_0000; end 3d5: begin ch6 db; channel_valid 8b0010_0000; end 3d6: begin ch7 db; channel_valid 8b0100_0000; end 3d7: begin ch8 db; channel_valid 8b1000_0000; end default: channel_valid 8d0; endcase end if (state ST_REPORT) frame_done 1b1; end end endmodule
返回列表