| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720 |
- `timescale 1ns/1ps
- module analog_ip (
- inout BAUD_RATE,
- inout TEST_SINGLE,
- inout UART1_RX,
- inout UART1_TX,
- inout so_io1,
- input csn_out_data,
- input csn_out_en,
- output tri0 rxd1_ip_in,
- input sck_out_data,
- input sck_out_en,
- output tri0 so_io1_in,
- input so_io1_out_data,
- input so_io1_out_en,
- input txd1_ip_out_data,
- input txd1_ip_out_en,
- input sys_clock,
- input bus_clock,
- input resetn,
- input stop,
- input [1:0] mem_ahb_htrans,
- input mem_ahb_hready,
- input mem_ahb_hwrite,
- input [31:0] mem_ahb_haddr,
- input [2:0] mem_ahb_hsize,
- input [2:0] mem_ahb_hburst,
- input [31:0] mem_ahb_hwdata,
- output tri1 mem_ahb_hreadyout,
- output tri0 mem_ahb_hresp,
- output tri0 [31:0] mem_ahb_hrdata,
- output tri0 slave_ahb_hsel,
- output tri1 slave_ahb_hready,
- input slave_ahb_hreadyout,
- output tri0 [1:0] slave_ahb_htrans,
- output tri0 [2:0] slave_ahb_hsize,
- output tri0 [2:0] slave_ahb_hburst,
- output tri0 slave_ahb_hwrite,
- output tri0 [31:0] slave_ahb_haddr,
- output tri0 [31:0] slave_ahb_hwdata,
- input slave_ahb_hresp,
- input [31:0] slave_ahb_hrdata,
- output tri0 [3:0] ext_dma_DMACBREQ,
- output tri0 [3:0] ext_dma_DMACLBREQ,
- output tri0 [3:0] ext_dma_DMACSREQ,
- output tri0 [3:0] ext_dma_DMACLSREQ,
- input [3:0] ext_dma_DMACCLR,
- input [3:0] ext_dma_DMACTC,
- output tri0 [3:0] local_int
- );
- assign UART1_TX = txd1_ip_out_en ? txd1_ip_out_data : 1'bz;
- assign rxd1_ip_in = UART1_RX;
- assign slave_ahb_hsel = 1'b0;
- assign slave_ahb_hready = 1'b1;
- assign slave_ahb_htrans = 2'b00;
- assign slave_ahb_hsize = 3'b000;
- assign slave_ahb_hburst = 3'b000;
- assign slave_ahb_hwrite = 1'b0;
- assign slave_ahb_haddr = 32'b0;
- assign slave_ahb_hwdata = 32'b0;
- assign ext_dma_DMACBREQ = 4'b0000; // 禁用DMA
- assign ext_dma_DMACLBREQ = 4'b0000;
- assign ext_dma_DMACSREQ = 4'b0000;
- assign ext_dma_DMACLSREQ = 4'b0000;
- assign local_int = 4'b0000; // 禁用中断
- // ==============================================
- // 核心RAM参数定义
- // ==============================================
- parameter RAM_SIZE = 2048; // 总容量:1024*16bit = 2048字节
- parameter RAM_DEPTH = 1024; // 数据深度:1024个
- parameter RAM_WIDTH = 16; // 数据位宽:16bit
- parameter ADDR_BITS = 16;
- parameter DATA_BITS = 32;
- parameter PER_BITS = 12;
- parameter PER_CNT = 4; // APB外设:ADC0(0)、DAC0(1),这里设置4是为了兼容3000地址的DAC0
- // 前四个地址用作说明 未实际使用对应变量
- // parameter ADC0_ADDR = 'h0000; // ADC0地址
- // parameter CFG_REG_ADDR = 'h1000; // 配置参数模块偏移地址
- // parameter TRIG_CTRL_ADDR= 'h2000; // 触发模块偏移地址
- // parameter DAC0_ADDR = 'h3000; // DAC0地址
- parameter RAM_BASE_ADDR = 'h6000; // 双口RAM APB地址 实际应用
- // ==============================================
- // AHB2APB 桥
- // ==============================================
- wire apb_psel;
- wire apb_penable;
- wire apb_pwrite;
- wire [ADDR_BITS-1:0] apb_paddr;
- wire [DATA_BITS-1:0] apb_pwdata;
- wire [3:0] apb_pstrb;
- wire [2:0] apb_pprot;
- wire apb_pready = 1'b1;
- wire apb_pslverr = 1'b0;
- reg [DATA_BITS-1:0] apb_prdata;
- wire apb_clock = bus_clock;
- ahb2apb #(ADDR_BITS, DATA_BITS) ahb2apb_inst(
- .reset (!resetn ),
- .ahb_clock (sys_clock ),
- .ahb_hmastlock(1'b0 ),
- .ahb_htrans (mem_ahb_htrans ),
- .ahb_hsel (1'b1 ),
- .ahb_hready (mem_ahb_hready ),
- .ahb_hwrite (mem_ahb_hwrite ),
- .ahb_haddr (mem_ahb_haddr[ADDR_BITS-1:0]),
- .ahb_hsize (mem_ahb_hsize ),
- .ahb_hburst (mem_ahb_hburst ),
- .ahb_hprot (4'b0011 ),
- .ahb_hwdata (mem_ahb_hwdata ),
- .ahb_hrdata (mem_ahb_hrdata ),
- .ahb_hreadyout(mem_ahb_hreadyout ),
- .ahb_hresp (mem_ahb_hresp ),
- .apb_clock (apb_clock ),
- .apb_psel (apb_psel ),
- .apb_penable (apb_penable ),
- .apb_pwrite (apb_pwrite ),
- .apb_paddr (apb_paddr ),
- .apb_pwdata (apb_pwdata ),
- .apb_pstrb (apb_pstrb ),
- .apb_pprot (apb_pprot ),
- .apb_pready (apb_pready ),
- .apb_pslverr (apb_pslverr ),
- .apb_prdata (apb_prdata )
- );
- // ==============================================
- // APB 外设选择
- // ==============================================
- wire [PER_CNT-1:0] select = 1 << (apb_paddr[ADDR_BITS-1:PER_BITS]);
- wire per_psel[PER_CNT];
- wire per_penable[PER_CNT];
- wire per_pwrite[PER_CNT];
- wire [PER_BITS-1:0] per_paddr[PER_CNT];
- wire [DATA_BITS-1:0] per_pwdata[PER_CNT];
- wire [DATA_BITS-1:0] per_prdata[PER_CNT];
- genvar i;
- generate
- for (i = 0; i < PER_CNT; i = i + 1) begin : gen_per
- assign per_psel[i] = apb_psel & select[i];
- assign per_penable[i] = apb_penable & select[i];
- assign per_pwrite[i] = apb_pwrite;
- assign per_paddr[i] = apb_paddr[PER_BITS-1:0];
- assign per_pwdata[i] = apb_pwdata;
- end
- endgenerate
- // ==============================================
- // 实例化 cfg_reg
- // ==============================================
- wire cfg_adc_en;
- wire [7:0] cfg_adc_clk_div;
- wire [3:0] cfg_adc_chnl_sel;
- wire [11:0] cfg_trig_threshold;
- wire [15:0] cfg_trig_pulse_width;
- wire [1:0] cfg_trig_edge;
- wire [1:0] cfg_trig_mode;
- wire [4:0] cfg_trig_time_slot;
- wire [15:0] cfg_trig_auto_timeout;
- wire cfg_adc_run;
- wire cfg_adc_restart;
- // 新增:DAC 配置信号
- wire cfg_dac_en;
- wire cfg_dac_run;
- wire [1:0] cfg_wave_type;
- wire [9:0] cfg_max_vol;
- wire [9:0] cfg_min_vol;
- wire [31:0] cfg_frequency;
- wire [7:0] cfg_duty_cycle;
- cfg_reg cfg_reg_inst(
- .pclk (apb_clock),
- .presetn (resetn),
- .paddr (per_paddr[1]),
- .pwrite (per_pwrite[1]),
- .pwdata (per_pwdata[1]),
- .prdata (per_prdata[1]),
- .psel (per_psel[1]),
- .penable (per_penable[1]),
- .adc_en (cfg_adc_en),
- .adc_clk_div (cfg_adc_clk_div),
- .adc_chnl_sel (cfg_adc_chnl_sel),
- .trig_threshold (cfg_trig_threshold),
- .trig_pulse_width (cfg_trig_pulse_width),
- .trig_edge (cfg_trig_edge),
- .trig_mode (cfg_trig_mode),
- .trig_time_slot (cfg_trig_time_slot),
- .trig_auto_timeout (cfg_trig_auto_timeout),
- .adc_run (cfg_adc_run),
- .adc_restart (cfg_adc_restart),
- // ********************** 新增:DAC 输出 **********************
- .dac_en (cfg_dac_en),
- .dac_run (cfg_dac_run),
- .wave_type (cfg_wave_type),
- .max_vol (cfg_max_vol),
- .min_vol (cfg_min_vol),
- .frequency (cfg_frequency),
- .duty_cycle (cfg_duty_cycle)
- );
- // ==============================================
- // 实例化 ADC0
- // ==============================================
- wire adc0_eoc;
- wire [11:0] adc0_data;
- apb_adc #(
- .SCLK_BIT(16)
- ) apb_adc0_inst(
- // APB接口
- .stop (stop ),
- .dma_req (), // 不使用DMA
- .dma_clr (1'b0), // DMA清零置0
- .apb_clock (apb_clock ),
- .apb_resetn (resetn ),
- .apb_psel (per_psel[0] ),
- .apb_penable(per_penable[0] ),
- .apb_pwrite (per_pwrite[0] ),
- .apb_paddr (per_paddr[0] ),
- .apb_pwdata (per_pwdata[0] ),
- .apb_prdata (per_prdata[0] ),
- // ADC采集数据输出信号
- .adc_eoc_out(adc0_eoc ),
- .adc_data_out(adc0_data ),
- // CFG信号
- .cfg_adc_en (cfg_adc_en),
- .cfg_adc_clk_div (cfg_adc_clk_div),
- .cfg_adc_chnl_sel (cfg_adc_chnl_sel)
- );
- // ==============================================
- // ADC 12位 → 16位:高4位补0
- // ==============================================
- // wire [RAM_WIDTH-1:0] adc0_data_16bit;
- // assign adc0_data_16bit = {4'b0000, adc0_data};
- //assign TEST_CLK = adc0_eoc;
- //assign TEST_APB_CLK = apb_clock;
- // ==============================================
- // 实例化 trig_ctrl
- // ==============================================
- wire [9:0] trig_ram_wr_addr;
- wire trig_ram_wren;
- wire [RAM_WIDTH-1:0] trig_ram_data_16bit;
- trig_ctrl trig_ctrl_inst(
- .pclk (apb_clock),
- .presetn (resetn),
- .paddr (per_paddr[2]),
- .pwrite (per_pwrite[2]),
- .pwdata (per_pwdata[2]),
- .prdata (per_prdata[2]),
- .psel (per_psel[2]),
- .penable (per_penable[2]),
- .trig_threshold (cfg_trig_threshold),
- .trig_pulse_width (cfg_trig_pulse_width),
- .trig_edge (cfg_trig_edge),
- .trig_mode (cfg_trig_mode),
- .trig_time_slot (cfg_trig_time_slot),
- .trig_auto_timeout (cfg_trig_auto_timeout),
- .adc_en (cfg_adc_en),
- .adc_run (cfg_adc_run),
- .adc_restart (cfg_adc_restart),
- .adc_eoc (adc0_eoc),
- .adc_data (adc0_data),
- .ram_wren_b (trig_ram_wren),
- .ram_wr_addr (trig_ram_wr_addr),
- .ram_wr_data_b (trig_ram_data_16bit),
-
- .trig_done (),
- .trigger_ptr ()
- );
- // ==============================================
- // 实例化 DAC0
- // ==============================================
- apb_dac apb_dac0_inst(
- .stop (stop),
- .dma_req (), // 不使用DMA
- .dma_clr (1'b0),
- .apb_clock (apb_clock ),
- .apb_resetn (resetn ),
- .apb_psel (per_psel[3] ),
- .apb_penable(per_penable[3] ),
- .apb_pwrite (per_pwrite[3] ),
- .apb_paddr (per_paddr[3] ),
- .apb_pwdata (per_pwdata[3] ),
- .apb_prdata (per_prdata[3] ),
- // ********************** 新增:波形控制参数 **********************
- .dac_en (cfg_dac_en),
- .dac_run (cfg_dac_run),
- .wave_type (cfg_wave_type),
- .max_vol (cfg_max_vol),
- .min_vol (cfg_min_vol),
- .frequency (cfg_frequency),
- .duty_cycle (cfg_duty_cycle),
- );
- // assign TEST_SINGLE = dac_test;
- // ==============================================
- // 实例化 波特率检测模块
- // ==============================================
- wire [31:0] baud_rate;
- baud_detect u_baud_detect (
- .sys_clock (sys_clock),
- .rst_n (resetn), // 顶层的复位信号(低有效)
- .UART1_DETECT (BAUD_RATE), // UART1_RX的FPGA输入信号
- .baud_rate (baud_rate) // 检测到的波特率
- );
- // ==============================================
- // 双口 RAM 配置(1024×16bit)
- // ==============================================
- wire [9:0] ram_addr_a; // MCU读地址(10bit,1024深度)
- wire [RAM_WIDTH-1:0] ram_data_a; // MCU写数据(不用)
- wire [RAM_WIDTH-1:0] ram_q_a; // MCU读数据(16位)
- wire ram_wren_a; // MCU写使能(不用)
- wire ram_rden_a; // MCU读使能
- wire [1:0] ram_byteena_a; // 16位RAM对应2位字节使能wire信号
- wire [9:0] ram_addr_b; // ADC写地址(10bit)
- wire [RAM_WIDTH-1:0] ram_data_b; // ADC写数据(16位)
- wire ram_wren_b; // ADC写使能(EOC控制)
- wire [RAM_WIDTH-1:0] ram_q_b; // 不用
- // 字节使能信号赋值(全使能)
- assign ram_byteena_a = 2'b11;
- // RAM B口地址自增(10bit,循环1024)
- // reg [9:0] ram_wr_addr_b_reg;
- // always @(posedge apb_clock or negedge resetn) begin
- // if(!resetn)
- // ram_wr_addr_b_reg <= 10'd0;
- // else if(adc0_eoc)
- // ram_wr_addr_b_reg <= ram_wr_addr_b_reg + 1'b1;
- // end
- // assign ram_addr_b = ram_wr_addr_b_reg;
- // assign ram_data_b = adc0_data_16bit; // 写入补0后的16位数据
- // assign ram_wren_b = adc0_eoc; // ADC采样完成立即写入RAM
- assign ram_wren_b = trig_ram_wren; // trig模块使能写
- assign ram_addr_b = trig_ram_wr_addr; // trig模块传输地址
- assign ram_data_b = trig_ram_data_16bit; // trig输出补位后的16位数据
-
- altsyncram u_dual_port_ram(
- .wren_a (ram_wren_a ), // MCU端口写使能
- .wren_b (ram_wren_b ), // ADC端口写使能
- .rden_a (ram_rden_a ), // MCU端口读使能
- .rden_b (1'b0 ), // ADC端口始终读使能
- .data_a (16'd0 ), // MCU端口写入数据(不用)
- .data_b (ram_data_b ), // ADC写入16bit数据
- .address_a (ram_addr_a ), // MCU地址(10bit)
- .address_b (ram_addr_b ), // ADC地址(10bit)
- .clock0 (apb_clock ), // 时钟端口0
- .clock1 (apb_clock ), // 时钟端口1
- .clocken0 (1'b1 ), // 时钟使能0
- .clocken1 (1'b1 ), // 时钟使能1
- .clocken2 (1'b1 ), // 时钟使能2
- .clocken3 (1'b1 ), // 时钟使能3
- .aclr0 (1'b0 ), // 清零0(禁用)
- .aclr1 (1'b0 ), // 清零1(禁用)
- .byteena_a (ram_byteena_a), // 连接wire信号,而非常量
- .byteena_b (2'b11 ), // ADC写全使能
- .addressstall_a(1'b0 ), // 地址暂停禁用
- .addressstall_b(1'b0 ), // 地址暂停禁用
- .q_a (ram_q_a ), // MCU读出16bit数据
- .q_b (), // ADC端口不读
- .eccstatus ( ) // ECC不用
- );
- // 适配1024×16bit
- defparam
- u_dual_port_ram.byte_size = 8,
- u_dual_port_ram.clock_enable_input_a = "BYPASS",
- u_dual_port_ram.clock_enable_output_a = "BYPASS",
- u_dual_port_ram.intended_device_family = "Cyclone IV E",
- u_dual_port_ram.lpm_hint = "ENABLE_RUNTIME_MOD=NO",
- u_dual_port_ram.operation_mode = "BIDIR_DUAL_PORT",
- u_dual_port_ram.numwords_a = 1024, // 深度1024
- u_dual_port_ram.widthad_a = 10, // 10bit地址
- u_dual_port_ram.width_a = 16, // 16bit位宽
- u_dual_port_ram.width_byteena_a = 2, // 2字节使能
- u_dual_port_ram.outdata_aclr_a = "NONE",
- u_dual_port_ram.outdata_reg_a = "UNREGISTERED",
- u_dual_port_ram.numwords_b = 1024, // 深度1024
- u_dual_port_ram.widthad_b = 10, // 10bit地址
- u_dual_port_ram.width_b = 16, // 16bit位宽
- u_dual_port_ram.width_byteena_b = 2, // 2字节使能
- u_dual_port_ram.outdata_aclr_b = "NONE",
- u_dual_port_ram.outdata_reg_b = "UNREGISTERED",
- u_dual_port_ram.ram_block_type = "M9K",
- u_dual_port_ram.read_during_write_mode_port_a = "NEW_DATA_NO_NBE_READ";
- // ==============================================
- // APB2RAM 例化(供MCU读取16位RAM数据)
- // ==============================================
- wire mem_apb_psel;
- wire mem_apb_penable;
- wire mem_apb_pwrite;
- wire [15:0] mem_apb_paddr;
- wire [31:0] mem_apb_pwdata;
- wire [3:0] mem_apb_pstrb;
- wire [2:0] mem_apb_pprot;
- wire mem_apb_pready;
- wire mem_apb_pslverr;
- wire [31:0] mem_apb_prdata; // 仅由apb2ram驱动,无外部赋值
- // RAM 地址选择
- assign mem_apb_psel = apb_psel && (apb_paddr[ADDR_BITS-1:PER_BITS] == RAM_BASE_ADDR[ADDR_BITS-1:PER_BITS]);
- assign mem_apb_penable = apb_penable;
- assign mem_apb_pwrite = apb_pwrite;
- assign mem_apb_paddr = apb_paddr;
- assign mem_apb_pwdata = apb_pwdata;
- assign mem_apb_pstrb = apb_pstrb;
- assign mem_apb_pprot = apb_pprot;
- apb2ram #(16) u_apb2ram(
- .resetn (resetn ),
- .apb_clock (bus_clock ),
- .apb_psel (mem_apb_psel ),
- .apb_penable(mem_apb_penable),
- .apb_pwrite (mem_apb_pwrite ),
- .apb_paddr (mem_apb_paddr ),
- .apb_pwdata (mem_apb_pwdata ),
- .apb_pstrb (mem_apb_pstrb ),
- .apb_pprot (mem_apb_pprot ),
- .apb_pready (mem_apb_pready ),
- .apb_pslverr(mem_apb_pslverr),
- .apb_prdata (mem_apb_prdata ), // 唯一驱动源
- .ram_addr (ram_addr_a ),
- .ram_byteena(ram_byteena_a ), // 连接wire信号,而非常量
- .ram_data (ram_data_a ),
- .ram_wren (ram_wren_a ),
- .ram_rden (ram_rden_a ),
- .ram_q (ram_q_a )
- );
- // ==============================================
- // APB 读数据合并
- // ==============================================
- reg [PER_CNT-1:0] pr_select;
- always @(posedge apb_clock or negedge resetn) begin
- if (!resetn)
- pr_select <= 'b0;
- else if (apb_psel && !apb_penable)
- pr_select <= select;
- end
- always @ (*) begin
- apb_prdata = 32'd0;
- if(mem_apb_psel) begin
- apb_prdata = mem_apb_prdata; // 读RAM
- end else begin
- // 关键:根据 pr_select 选择对应外设的读数据(多选一)
- case (pr_select)
- 4'b0001: apb_prdata = per_prdata[0]; // 读ADC0
- 4'b0010: apb_prdata = per_prdata[1]; // 读CFG_REG(TRIG_CONFIG 正常)
- 4'b0100: apb_prdata = per_prdata[2]; // 读TRIG_CTRL(TRIG_PTR 正常)
- 4'b1000: apb_prdata = per_prdata[3]; // 读DAC0
- default: apb_prdata = 32'd0;
- endcase
- end
- end
- // integer j;
- // always @ (*) begin
- // apb_prdata = 32'd0;
- // if(mem_apb_psel)
- // apb_prdata = mem_apb_prdata; // 读RAM
- // else
- // for (j = 0; j < PER_CNT; j = j + 1)
- // apb_prdata = apb_prdata | per_prdata[j];
- // end
- endmodule
- module apb_adc (
- input stop,
- output dma_req,
- input dma_clr,
- input apb_clock,
- input apb_resetn,
- input apb_psel,
- input apb_penable,
- input apb_pwrite,
- input [11:0] apb_paddr,
- input [31:0] apb_pwdata,
- output [31:0] apb_prdata,
- // ===================== ADC模块输出信号 =====================
- output adc_eoc_out, // 采集完成脉冲
- output [11:0] adc_data_out, // 通道12稳定数据
- // ===================== CFG全局配置输入信号(现在生效!) =====================
- input cfg_adc_en, // ADC总使能(取代原ADC_CONT_EN)
- input [7:0] cfg_adc_clk_div, // 时钟分频(取代原SCLK_DIV)
- input [3:0] cfg_adc_chnl_sel // 通道选择(取代原FIXED_CHANNEL)
- );
- parameter SCLK_BIT = 16;
- // 核心信号
- reg apb_eoc;
- reg [11:0] apb_db;
- wire adc_eoc;
- wire [11:0] adc_db;
- wire eoc_rising = (!adc_eoc) && apb_eoc; // 采集完成上升沿
- // 时钟分频信号
- reg [SCLK_BIT-1:0] sclk_counter;
- reg sclk;
- // EOC同步(标准2拍同步,稳定可靠)
- always @(posedge apb_clock or negedge apb_resetn) begin
- if (!apb_resetn)
- apb_eoc <= 1'b0;
- else
- apb_eoc <= adc_eoc;
- end
- // 数据锁存(仅ADC使能时,采集完成锁存数据)
- always @(posedge apb_clock or negedge apb_resetn) begin
- if (!apb_resetn)
- apb_db <= 12'b0;
- else if (cfg_adc_en && eoc_rising) //使用cfg使能
- apb_db <= adc_db;
- end
- // 时钟分频逻辑(分频值 来自cfg_adc_clk_div)
- always @(posedge apb_clock or negedge apb_resetn) begin
- if (!apb_resetn) begin
- sclk_counter <= 0;
- sclk <= 1'b0;
- end
- else if (!cfg_adc_en) begin // ADC关闭时,分频器复位
- sclk_counter <= 0;
- sclk <= 1'b0;
- end
- else begin // ADC使能时,正常分频
- if (sclk_counter == cfg_adc_clk_div) begin //分频值用cfg配置
- sclk_counter <= 0;
- sclk <= !sclk;
- end
- else begin
- sclk_counter <= sclk_counter + 1'b1;
- end
- end
- end
- // 输出信号
- assign adc_eoc_out = eoc_rising;
- assign adc_data_out = apb_db;
- wire [4:0] chnl_sel = cfg_adc_chnl_sel;
- assign dma_req = 1'b0;
- assign apb_prdata = 32'd0;
- // ADC硬核(所有配置均来自外部CFG,无任何硬编码!)
- alta_adc adc_inst(
- .enb (!cfg_adc_en), // 使能来自cfg
- .sclk (sclk), // 分频时钟来自cfg配置
- .insel(chnl_sel), // 通道来自cfg配置
- .stop (stop),
- .db (adc_db),
- .eoc (adc_eoc)
- );
- endmodule
- // ==============================================
- // apb_dac 模块
- // ==============================================
- module apb_dac (
- input stop,
- output dma_req,
- input dma_clr,
- input apb_clock,
- input apb_resetn,
- input apb_psel,
- input apb_penable,
- input apb_pwrite,
- input [11:0] apb_paddr,
- input [31:0] apb_pwdata,
- output [31:0] apb_prdata,
- input dac_en, // 来自 CFG
- input dac_run, // 来自 CFG
- input [1:0] wave_type, // 来自 CFG
- input [9:0] max_vol, // 来自 CFG
- input [9:0] min_vol, // 来自 CFG
- input [31:0] frequency, // 来自 CFG
- input [7:0] duty_cycle // 来自 CFG
- );
- assign dma_req = 1'b0;
- assign apb_prdata = 32'd0;
- // ------------------- DDS 相位累加器(核心,只有加法)-------------------
- reg [31:0] phase_acc;
- always @(posedge apb_clock or negedge apb_resetn) begin
- if (!apb_resetn) begin
- phase_acc <= 32'd0;
- end else begin
- if (!dac_en || !dac_run) begin
- phase_acc <= 32'd0;
- end
- else begin
- phase_acc <= phase_acc + frequency;
- end
- end
- end
- wire [9:0] phase_comb = phase_acc[31:22]; // 10 位相位(组合)
- // // ========== 正弦查找表 ROM(组合读取) ==========
- (* ram_style = "distributed" *) // 强制综合为分布式 RAM,允许组合读出
- reg [9:0] sine_rom [0:1023];
- //(* ram_style = "block" *) reg [9:0] sine_rom [0:1023];
- initial begin
- $readmemh("sine.hex", sine_rom);
- end
- // // 组合读取:用 phase_r 作为地址直接出数据
- wire [9:0] sin_raw;
- assign sin_raw = sine_rom[phase_r];
- // ---------- 同步所有参与运算的信号 ----------
- // 目的:让 max_vol, min_vol, phase 在时钟沿后稳定,消除输入跳变引起的毛刺
- reg [9:0] max_vol_r, min_vol_r;
- reg [9:0] phase_r;
- reg phase_msb_r; // phase_acc[31] 用于方波
- always @(posedge apb_clock) begin
- max_vol_r <= max_vol;
- min_vol_r <= min_vol;
- phase_r <= phase_comb;
- phase_msb_r <= phase_acc[31];
- end
- // ---------- 组合逻辑:波形计算(纯组合,无毛刺输入)----------
- reg [9:0] wave_data_comb;
- reg [9:0] diff;
- reg [19:0] mult;
- reg [9:0] step;
- always @(*) begin
- // 使用寄存后的稳定值进行计算
- diff = max_vol_r - min_vol_r;
- case(wave_type)
- 2'b00: begin // 方波
- wave_data_comb = (phase_msb_r == 1'b0) ? max_vol_r : min_vol_r;
- end
- 2'b01: begin // 正弦波(查表 + 幅度缩放)
- mult = diff * sin_raw; // sin_raw 为 0~1023,中心 512
- step = mult >> 10; // 除以 1024
- wave_data_comb = min_vol_r + step;
- end
- 2'b10: begin // 三角波
- if (phase_r[9] == 1'b0) begin
- // 上升支:phase 0~511
- mult = diff * phase_r[8:0];
- step = mult >> 9;
- wave_data_comb = min_vol_r + step;
- end else begin
- // 下降支:phase 512~1023,phase_r[8:0] 实际等于 phase-512
- mult = diff * phase_r[8:0];
- step = mult >> 9;
- // 理论上 step <= diff,这里加个安全钳位
- wave_data_comb = (max_vol_r > step) ? (max_vol_r - step) : min_vol_r;
- end
- end
- 2'b11: begin // 锯齿波
- mult = diff * phase_r;
- step = mult >> 10; // 除以 1024,近似斜坡
- wave_data_comb = min_vol_r + step;
- end
- default: wave_data_comb = 10'd0;
- endcase
- end
- // ------------------------------
- // 关键:完全对齐官方极性
- // ------------------------------
- wire dac_dout;
- alta_dac dac_inst(
- .enb (!dac_en), // 低有效
- .bufenb (!dac_en), // 低有效 (用dac_en控制即可)
- .din (wave_data_comb), // 波形数据
- .stop (stop),
- .dout (dac_dout)
- );
- endmodule
|