analog_ip.v 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720
  1. `timescale 1ns/1ps
  2. module analog_ip (
  3. inout BAUD_RATE,
  4. inout TEST_SINGLE,
  5. inout UART1_RX,
  6. inout UART1_TX,
  7. inout so_io1,
  8. input csn_out_data,
  9. input csn_out_en,
  10. output tri0 rxd1_ip_in,
  11. input sck_out_data,
  12. input sck_out_en,
  13. output tri0 so_io1_in,
  14. input so_io1_out_data,
  15. input so_io1_out_en,
  16. input txd1_ip_out_data,
  17. input txd1_ip_out_en,
  18. input sys_clock,
  19. input bus_clock,
  20. input resetn,
  21. input stop,
  22. input [1:0] mem_ahb_htrans,
  23. input mem_ahb_hready,
  24. input mem_ahb_hwrite,
  25. input [31:0] mem_ahb_haddr,
  26. input [2:0] mem_ahb_hsize,
  27. input [2:0] mem_ahb_hburst,
  28. input [31:0] mem_ahb_hwdata,
  29. output tri1 mem_ahb_hreadyout,
  30. output tri0 mem_ahb_hresp,
  31. output tri0 [31:0] mem_ahb_hrdata,
  32. output tri0 slave_ahb_hsel,
  33. output tri1 slave_ahb_hready,
  34. input slave_ahb_hreadyout,
  35. output tri0 [1:0] slave_ahb_htrans,
  36. output tri0 [2:0] slave_ahb_hsize,
  37. output tri0 [2:0] slave_ahb_hburst,
  38. output tri0 slave_ahb_hwrite,
  39. output tri0 [31:0] slave_ahb_haddr,
  40. output tri0 [31:0] slave_ahb_hwdata,
  41. input slave_ahb_hresp,
  42. input [31:0] slave_ahb_hrdata,
  43. output tri0 [3:0] ext_dma_DMACBREQ,
  44. output tri0 [3:0] ext_dma_DMACLBREQ,
  45. output tri0 [3:0] ext_dma_DMACSREQ,
  46. output tri0 [3:0] ext_dma_DMACLSREQ,
  47. input [3:0] ext_dma_DMACCLR,
  48. input [3:0] ext_dma_DMACTC,
  49. output tri0 [3:0] local_int
  50. );
  51. assign UART1_TX = txd1_ip_out_en ? txd1_ip_out_data : 1'bz;
  52. assign rxd1_ip_in = UART1_RX;
  53. assign slave_ahb_hsel = 1'b0;
  54. assign slave_ahb_hready = 1'b1;
  55. assign slave_ahb_htrans = 2'b00;
  56. assign slave_ahb_hsize = 3'b000;
  57. assign slave_ahb_hburst = 3'b000;
  58. assign slave_ahb_hwrite = 1'b0;
  59. assign slave_ahb_haddr = 32'b0;
  60. assign slave_ahb_hwdata = 32'b0;
  61. assign ext_dma_DMACBREQ = 4'b0000; // 禁用DMA
  62. assign ext_dma_DMACLBREQ = 4'b0000;
  63. assign ext_dma_DMACSREQ = 4'b0000;
  64. assign ext_dma_DMACLSREQ = 4'b0000;
  65. assign local_int = 4'b0000; // 禁用中断
  66. // ==============================================
  67. // 核心RAM参数定义
  68. // ==============================================
  69. parameter RAM_SIZE = 2048; // 总容量:1024*16bit = 2048字节
  70. parameter RAM_DEPTH = 1024; // 数据深度:1024个
  71. parameter RAM_WIDTH = 16; // 数据位宽:16bit
  72. parameter ADDR_BITS = 16;
  73. parameter DATA_BITS = 32;
  74. parameter PER_BITS = 12;
  75. parameter PER_CNT = 4; // APB外设:ADC0(0)、DAC0(1),这里设置4是为了兼容3000地址的DAC0
  76. // 前四个地址用作说明 未实际使用对应变量
  77. // parameter ADC0_ADDR = 'h0000; // ADC0地址
  78. // parameter CFG_REG_ADDR = 'h1000; // 配置参数模块偏移地址
  79. // parameter TRIG_CTRL_ADDR= 'h2000; // 触发模块偏移地址
  80. // parameter DAC0_ADDR = 'h3000; // DAC0地址
  81. parameter RAM_BASE_ADDR = 'h6000; // 双口RAM APB地址 实际应用
  82. // ==============================================
  83. // AHB2APB 桥
  84. // ==============================================
  85. wire apb_psel;
  86. wire apb_penable;
  87. wire apb_pwrite;
  88. wire [ADDR_BITS-1:0] apb_paddr;
  89. wire [DATA_BITS-1:0] apb_pwdata;
  90. wire [3:0] apb_pstrb;
  91. wire [2:0] apb_pprot;
  92. wire apb_pready = 1'b1;
  93. wire apb_pslverr = 1'b0;
  94. reg [DATA_BITS-1:0] apb_prdata;
  95. wire apb_clock = bus_clock;
  96. ahb2apb #(ADDR_BITS, DATA_BITS) ahb2apb_inst(
  97. .reset (!resetn ),
  98. .ahb_clock (sys_clock ),
  99. .ahb_hmastlock(1'b0 ),
  100. .ahb_htrans (mem_ahb_htrans ),
  101. .ahb_hsel (1'b1 ),
  102. .ahb_hready (mem_ahb_hready ),
  103. .ahb_hwrite (mem_ahb_hwrite ),
  104. .ahb_haddr (mem_ahb_haddr[ADDR_BITS-1:0]),
  105. .ahb_hsize (mem_ahb_hsize ),
  106. .ahb_hburst (mem_ahb_hburst ),
  107. .ahb_hprot (4'b0011 ),
  108. .ahb_hwdata (mem_ahb_hwdata ),
  109. .ahb_hrdata (mem_ahb_hrdata ),
  110. .ahb_hreadyout(mem_ahb_hreadyout ),
  111. .ahb_hresp (mem_ahb_hresp ),
  112. .apb_clock (apb_clock ),
  113. .apb_psel (apb_psel ),
  114. .apb_penable (apb_penable ),
  115. .apb_pwrite (apb_pwrite ),
  116. .apb_paddr (apb_paddr ),
  117. .apb_pwdata (apb_pwdata ),
  118. .apb_pstrb (apb_pstrb ),
  119. .apb_pprot (apb_pprot ),
  120. .apb_pready (apb_pready ),
  121. .apb_pslverr (apb_pslverr ),
  122. .apb_prdata (apb_prdata )
  123. );
  124. // ==============================================
  125. // APB 外设选择
  126. // ==============================================
  127. wire [PER_CNT-1:0] select = 1 << (apb_paddr[ADDR_BITS-1:PER_BITS]);
  128. wire per_psel[PER_CNT];
  129. wire per_penable[PER_CNT];
  130. wire per_pwrite[PER_CNT];
  131. wire [PER_BITS-1:0] per_paddr[PER_CNT];
  132. wire [DATA_BITS-1:0] per_pwdata[PER_CNT];
  133. wire [DATA_BITS-1:0] per_prdata[PER_CNT];
  134. genvar i;
  135. generate
  136. for (i = 0; i < PER_CNT; i = i + 1) begin : gen_per
  137. assign per_psel[i] = apb_psel & select[i];
  138. assign per_penable[i] = apb_penable & select[i];
  139. assign per_pwrite[i] = apb_pwrite;
  140. assign per_paddr[i] = apb_paddr[PER_BITS-1:0];
  141. assign per_pwdata[i] = apb_pwdata;
  142. end
  143. endgenerate
  144. // ==============================================
  145. // 实例化 cfg_reg
  146. // ==============================================
  147. wire cfg_adc_en;
  148. wire [7:0] cfg_adc_clk_div;
  149. wire [3:0] cfg_adc_chnl_sel;
  150. wire [11:0] cfg_trig_threshold;
  151. wire [15:0] cfg_trig_pulse_width;
  152. wire [1:0] cfg_trig_edge;
  153. wire [1:0] cfg_trig_mode;
  154. wire [4:0] cfg_trig_time_slot;
  155. wire [15:0] cfg_trig_auto_timeout;
  156. wire cfg_adc_run;
  157. wire cfg_adc_restart;
  158. // 新增:DAC 配置信号
  159. wire cfg_dac_en;
  160. wire cfg_dac_run;
  161. wire [1:0] cfg_wave_type;
  162. wire [9:0] cfg_max_vol;
  163. wire [9:0] cfg_min_vol;
  164. wire [31:0] cfg_frequency;
  165. wire [7:0] cfg_duty_cycle;
  166. cfg_reg cfg_reg_inst(
  167. .pclk (apb_clock),
  168. .presetn (resetn),
  169. .paddr (per_paddr[1]),
  170. .pwrite (per_pwrite[1]),
  171. .pwdata (per_pwdata[1]),
  172. .prdata (per_prdata[1]),
  173. .psel (per_psel[1]),
  174. .penable (per_penable[1]),
  175. .adc_en (cfg_adc_en),
  176. .adc_clk_div (cfg_adc_clk_div),
  177. .adc_chnl_sel (cfg_adc_chnl_sel),
  178. .trig_threshold (cfg_trig_threshold),
  179. .trig_pulse_width (cfg_trig_pulse_width),
  180. .trig_edge (cfg_trig_edge),
  181. .trig_mode (cfg_trig_mode),
  182. .trig_time_slot (cfg_trig_time_slot),
  183. .trig_auto_timeout (cfg_trig_auto_timeout),
  184. .adc_run (cfg_adc_run),
  185. .adc_restart (cfg_adc_restart),
  186. // ********************** 新增:DAC 输出 **********************
  187. .dac_en (cfg_dac_en),
  188. .dac_run (cfg_dac_run),
  189. .wave_type (cfg_wave_type),
  190. .max_vol (cfg_max_vol),
  191. .min_vol (cfg_min_vol),
  192. .frequency (cfg_frequency),
  193. .duty_cycle (cfg_duty_cycle)
  194. );
  195. // ==============================================
  196. // 实例化 ADC0
  197. // ==============================================
  198. wire adc0_eoc;
  199. wire [11:0] adc0_data;
  200. apb_adc #(
  201. .SCLK_BIT(16)
  202. ) apb_adc0_inst(
  203. // APB接口
  204. .stop (stop ),
  205. .dma_req (), // 不使用DMA
  206. .dma_clr (1'b0), // DMA清零置0
  207. .apb_clock (apb_clock ),
  208. .apb_resetn (resetn ),
  209. .apb_psel (per_psel[0] ),
  210. .apb_penable(per_penable[0] ),
  211. .apb_pwrite (per_pwrite[0] ),
  212. .apb_paddr (per_paddr[0] ),
  213. .apb_pwdata (per_pwdata[0] ),
  214. .apb_prdata (per_prdata[0] ),
  215. // ADC采集数据输出信号
  216. .adc_eoc_out(adc0_eoc ),
  217. .adc_data_out(adc0_data ),
  218. // CFG信号
  219. .cfg_adc_en (cfg_adc_en),
  220. .cfg_adc_clk_div (cfg_adc_clk_div),
  221. .cfg_adc_chnl_sel (cfg_adc_chnl_sel)
  222. );
  223. // ==============================================
  224. // ADC 12位 → 16位:高4位补0
  225. // ==============================================
  226. // wire [RAM_WIDTH-1:0] adc0_data_16bit;
  227. // assign adc0_data_16bit = {4'b0000, adc0_data};
  228. //assign TEST_CLK = adc0_eoc;
  229. //assign TEST_APB_CLK = apb_clock;
  230. // ==============================================
  231. // 实例化 trig_ctrl
  232. // ==============================================
  233. wire [9:0] trig_ram_wr_addr;
  234. wire trig_ram_wren;
  235. wire [RAM_WIDTH-1:0] trig_ram_data_16bit;
  236. trig_ctrl trig_ctrl_inst(
  237. .pclk (apb_clock),
  238. .presetn (resetn),
  239. .paddr (per_paddr[2]),
  240. .pwrite (per_pwrite[2]),
  241. .pwdata (per_pwdata[2]),
  242. .prdata (per_prdata[2]),
  243. .psel (per_psel[2]),
  244. .penable (per_penable[2]),
  245. .trig_threshold (cfg_trig_threshold),
  246. .trig_pulse_width (cfg_trig_pulse_width),
  247. .trig_edge (cfg_trig_edge),
  248. .trig_mode (cfg_trig_mode),
  249. .trig_time_slot (cfg_trig_time_slot),
  250. .trig_auto_timeout (cfg_trig_auto_timeout),
  251. .adc_en (cfg_adc_en),
  252. .adc_run (cfg_adc_run),
  253. .adc_restart (cfg_adc_restart),
  254. .adc_eoc (adc0_eoc),
  255. .adc_data (adc0_data),
  256. .ram_wren_b (trig_ram_wren),
  257. .ram_wr_addr (trig_ram_wr_addr),
  258. .ram_wr_data_b (trig_ram_data_16bit),
  259. .trig_done (),
  260. .trigger_ptr ()
  261. );
  262. // ==============================================
  263. // 实例化 DAC0
  264. // ==============================================
  265. apb_dac apb_dac0_inst(
  266. .stop (stop),
  267. .dma_req (), // 不使用DMA
  268. .dma_clr (1'b0),
  269. .apb_clock (apb_clock ),
  270. .apb_resetn (resetn ),
  271. .apb_psel (per_psel[3] ),
  272. .apb_penable(per_penable[3] ),
  273. .apb_pwrite (per_pwrite[3] ),
  274. .apb_paddr (per_paddr[3] ),
  275. .apb_pwdata (per_pwdata[3] ),
  276. .apb_prdata (per_prdata[3] ),
  277. // ********************** 新增:波形控制参数 **********************
  278. .dac_en (cfg_dac_en),
  279. .dac_run (cfg_dac_run),
  280. .wave_type (cfg_wave_type),
  281. .max_vol (cfg_max_vol),
  282. .min_vol (cfg_min_vol),
  283. .frequency (cfg_frequency),
  284. .duty_cycle (cfg_duty_cycle),
  285. );
  286. // assign TEST_SINGLE = dac_test;
  287. // ==============================================
  288. // 实例化 波特率检测模块
  289. // ==============================================
  290. wire [31:0] baud_rate;
  291. baud_detect u_baud_detect (
  292. .sys_clock (sys_clock),
  293. .rst_n (resetn), // 顶层的复位信号(低有效)
  294. .UART1_DETECT (BAUD_RATE), // UART1_RX的FPGA输入信号
  295. .baud_rate (baud_rate) // 检测到的波特率
  296. );
  297. // ==============================================
  298. // 双口 RAM 配置(1024×16bit)
  299. // ==============================================
  300. wire [9:0] ram_addr_a; // MCU读地址(10bit,1024深度)
  301. wire [RAM_WIDTH-1:0] ram_data_a; // MCU写数据(不用)
  302. wire [RAM_WIDTH-1:0] ram_q_a; // MCU读数据(16位)
  303. wire ram_wren_a; // MCU写使能(不用)
  304. wire ram_rden_a; // MCU读使能
  305. wire [1:0] ram_byteena_a; // 16位RAM对应2位字节使能wire信号
  306. wire [9:0] ram_addr_b; // ADC写地址(10bit)
  307. wire [RAM_WIDTH-1:0] ram_data_b; // ADC写数据(16位)
  308. wire ram_wren_b; // ADC写使能(EOC控制)
  309. wire [RAM_WIDTH-1:0] ram_q_b; // 不用
  310. // 字节使能信号赋值(全使能)
  311. assign ram_byteena_a = 2'b11;
  312. // RAM B口地址自增(10bit,循环1024)
  313. // reg [9:0] ram_wr_addr_b_reg;
  314. // always @(posedge apb_clock or negedge resetn) begin
  315. // if(!resetn)
  316. // ram_wr_addr_b_reg <= 10'd0;
  317. // else if(adc0_eoc)
  318. // ram_wr_addr_b_reg <= ram_wr_addr_b_reg + 1'b1;
  319. // end
  320. // assign ram_addr_b = ram_wr_addr_b_reg;
  321. // assign ram_data_b = adc0_data_16bit; // 写入补0后的16位数据
  322. // assign ram_wren_b = adc0_eoc; // ADC采样完成立即写入RAM
  323. assign ram_wren_b = trig_ram_wren; // trig模块使能写
  324. assign ram_addr_b = trig_ram_wr_addr; // trig模块传输地址
  325. assign ram_data_b = trig_ram_data_16bit; // trig输出补位后的16位数据
  326. altsyncram u_dual_port_ram(
  327. .wren_a (ram_wren_a ), // MCU端口写使能
  328. .wren_b (ram_wren_b ), // ADC端口写使能
  329. .rden_a (ram_rden_a ), // MCU端口读使能
  330. .rden_b (1'b0 ), // ADC端口始终读使能
  331. .data_a (16'd0 ), // MCU端口写入数据(不用)
  332. .data_b (ram_data_b ), // ADC写入16bit数据
  333. .address_a (ram_addr_a ), // MCU地址(10bit)
  334. .address_b (ram_addr_b ), // ADC地址(10bit)
  335. .clock0 (apb_clock ), // 时钟端口0
  336. .clock1 (apb_clock ), // 时钟端口1
  337. .clocken0 (1'b1 ), // 时钟使能0
  338. .clocken1 (1'b1 ), // 时钟使能1
  339. .clocken2 (1'b1 ), // 时钟使能2
  340. .clocken3 (1'b1 ), // 时钟使能3
  341. .aclr0 (1'b0 ), // 清零0(禁用)
  342. .aclr1 (1'b0 ), // 清零1(禁用)
  343. .byteena_a (ram_byteena_a), // 连接wire信号,而非常量
  344. .byteena_b (2'b11 ), // ADC写全使能
  345. .addressstall_a(1'b0 ), // 地址暂停禁用
  346. .addressstall_b(1'b0 ), // 地址暂停禁用
  347. .q_a (ram_q_a ), // MCU读出16bit数据
  348. .q_b (), // ADC端口不读
  349. .eccstatus ( ) // ECC不用
  350. );
  351. // 适配1024×16bit
  352. defparam
  353. u_dual_port_ram.byte_size = 8,
  354. u_dual_port_ram.clock_enable_input_a = "BYPASS",
  355. u_dual_port_ram.clock_enable_output_a = "BYPASS",
  356. u_dual_port_ram.intended_device_family = "Cyclone IV E",
  357. u_dual_port_ram.lpm_hint = "ENABLE_RUNTIME_MOD=NO",
  358. u_dual_port_ram.operation_mode = "BIDIR_DUAL_PORT",
  359. u_dual_port_ram.numwords_a = 1024, // 深度1024
  360. u_dual_port_ram.widthad_a = 10, // 10bit地址
  361. u_dual_port_ram.width_a = 16, // 16bit位宽
  362. u_dual_port_ram.width_byteena_a = 2, // 2字节使能
  363. u_dual_port_ram.outdata_aclr_a = "NONE",
  364. u_dual_port_ram.outdata_reg_a = "UNREGISTERED",
  365. u_dual_port_ram.numwords_b = 1024, // 深度1024
  366. u_dual_port_ram.widthad_b = 10, // 10bit地址
  367. u_dual_port_ram.width_b = 16, // 16bit位宽
  368. u_dual_port_ram.width_byteena_b = 2, // 2字节使能
  369. u_dual_port_ram.outdata_aclr_b = "NONE",
  370. u_dual_port_ram.outdata_reg_b = "UNREGISTERED",
  371. u_dual_port_ram.ram_block_type = "M9K",
  372. u_dual_port_ram.read_during_write_mode_port_a = "NEW_DATA_NO_NBE_READ";
  373. // ==============================================
  374. // APB2RAM 例化(供MCU读取16位RAM数据)
  375. // ==============================================
  376. wire mem_apb_psel;
  377. wire mem_apb_penable;
  378. wire mem_apb_pwrite;
  379. wire [15:0] mem_apb_paddr;
  380. wire [31:0] mem_apb_pwdata;
  381. wire [3:0] mem_apb_pstrb;
  382. wire [2:0] mem_apb_pprot;
  383. wire mem_apb_pready;
  384. wire mem_apb_pslverr;
  385. wire [31:0] mem_apb_prdata; // 仅由apb2ram驱动,无外部赋值
  386. // RAM 地址选择
  387. assign mem_apb_psel = apb_psel && (apb_paddr[ADDR_BITS-1:PER_BITS] == RAM_BASE_ADDR[ADDR_BITS-1:PER_BITS]);
  388. assign mem_apb_penable = apb_penable;
  389. assign mem_apb_pwrite = apb_pwrite;
  390. assign mem_apb_paddr = apb_paddr;
  391. assign mem_apb_pwdata = apb_pwdata;
  392. assign mem_apb_pstrb = apb_pstrb;
  393. assign mem_apb_pprot = apb_pprot;
  394. apb2ram #(16) u_apb2ram(
  395. .resetn (resetn ),
  396. .apb_clock (bus_clock ),
  397. .apb_psel (mem_apb_psel ),
  398. .apb_penable(mem_apb_penable),
  399. .apb_pwrite (mem_apb_pwrite ),
  400. .apb_paddr (mem_apb_paddr ),
  401. .apb_pwdata (mem_apb_pwdata ),
  402. .apb_pstrb (mem_apb_pstrb ),
  403. .apb_pprot (mem_apb_pprot ),
  404. .apb_pready (mem_apb_pready ),
  405. .apb_pslverr(mem_apb_pslverr),
  406. .apb_prdata (mem_apb_prdata ), // 唯一驱动源
  407. .ram_addr (ram_addr_a ),
  408. .ram_byteena(ram_byteena_a ), // 连接wire信号,而非常量
  409. .ram_data (ram_data_a ),
  410. .ram_wren (ram_wren_a ),
  411. .ram_rden (ram_rden_a ),
  412. .ram_q (ram_q_a )
  413. );
  414. // ==============================================
  415. // APB 读数据合并
  416. // ==============================================
  417. reg [PER_CNT-1:0] pr_select;
  418. always @(posedge apb_clock or negedge resetn) begin
  419. if (!resetn)
  420. pr_select <= 'b0;
  421. else if (apb_psel && !apb_penable)
  422. pr_select <= select;
  423. end
  424. always @ (*) begin
  425. apb_prdata = 32'd0;
  426. if(mem_apb_psel) begin
  427. apb_prdata = mem_apb_prdata; // 读RAM
  428. end else begin
  429. // 关键:根据 pr_select 选择对应外设的读数据(多选一)
  430. case (pr_select)
  431. 4'b0001: apb_prdata = per_prdata[0]; // 读ADC0
  432. 4'b0010: apb_prdata = per_prdata[1]; // 读CFG_REG(TRIG_CONFIG 正常)
  433. 4'b0100: apb_prdata = per_prdata[2]; // 读TRIG_CTRL(TRIG_PTR 正常)
  434. 4'b1000: apb_prdata = per_prdata[3]; // 读DAC0
  435. default: apb_prdata = 32'd0;
  436. endcase
  437. end
  438. end
  439. // integer j;
  440. // always @ (*) begin
  441. // apb_prdata = 32'd0;
  442. // if(mem_apb_psel)
  443. // apb_prdata = mem_apb_prdata; // 读RAM
  444. // else
  445. // for (j = 0; j < PER_CNT; j = j + 1)
  446. // apb_prdata = apb_prdata | per_prdata[j];
  447. // end
  448. endmodule
  449. module apb_adc (
  450. input stop,
  451. output dma_req,
  452. input dma_clr,
  453. input apb_clock,
  454. input apb_resetn,
  455. input apb_psel,
  456. input apb_penable,
  457. input apb_pwrite,
  458. input [11:0] apb_paddr,
  459. input [31:0] apb_pwdata,
  460. output [31:0] apb_prdata,
  461. // ===================== ADC模块输出信号 =====================
  462. output adc_eoc_out, // 采集完成脉冲
  463. output [11:0] adc_data_out, // 通道12稳定数据
  464. // ===================== CFG全局配置输入信号(现在生效!) =====================
  465. input cfg_adc_en, // ADC总使能(取代原ADC_CONT_EN)
  466. input [7:0] cfg_adc_clk_div, // 时钟分频(取代原SCLK_DIV)
  467. input [3:0] cfg_adc_chnl_sel // 通道选择(取代原FIXED_CHANNEL)
  468. );
  469. parameter SCLK_BIT = 16;
  470. // 核心信号
  471. reg apb_eoc;
  472. reg [11:0] apb_db;
  473. wire adc_eoc;
  474. wire [11:0] adc_db;
  475. wire eoc_rising = (!adc_eoc) && apb_eoc; // 采集完成上升沿
  476. // 时钟分频信号
  477. reg [SCLK_BIT-1:0] sclk_counter;
  478. reg sclk;
  479. // EOC同步(标准2拍同步,稳定可靠)
  480. always @(posedge apb_clock or negedge apb_resetn) begin
  481. if (!apb_resetn)
  482. apb_eoc <= 1'b0;
  483. else
  484. apb_eoc <= adc_eoc;
  485. end
  486. // 数据锁存(仅ADC使能时,采集完成锁存数据)
  487. always @(posedge apb_clock or negedge apb_resetn) begin
  488. if (!apb_resetn)
  489. apb_db <= 12'b0;
  490. else if (cfg_adc_en && eoc_rising) //使用cfg使能
  491. apb_db <= adc_db;
  492. end
  493. // 时钟分频逻辑(分频值 来自cfg_adc_clk_div)
  494. always @(posedge apb_clock or negedge apb_resetn) begin
  495. if (!apb_resetn) begin
  496. sclk_counter <= 0;
  497. sclk <= 1'b0;
  498. end
  499. else if (!cfg_adc_en) begin // ADC关闭时,分频器复位
  500. sclk_counter <= 0;
  501. sclk <= 1'b0;
  502. end
  503. else begin // ADC使能时,正常分频
  504. if (sclk_counter == cfg_adc_clk_div) begin //分频值用cfg配置
  505. sclk_counter <= 0;
  506. sclk <= !sclk;
  507. end
  508. else begin
  509. sclk_counter <= sclk_counter + 1'b1;
  510. end
  511. end
  512. end
  513. // 输出信号
  514. assign adc_eoc_out = eoc_rising;
  515. assign adc_data_out = apb_db;
  516. wire [4:0] chnl_sel = cfg_adc_chnl_sel;
  517. assign dma_req = 1'b0;
  518. assign apb_prdata = 32'd0;
  519. // ADC硬核(所有配置均来自外部CFG,无任何硬编码!)
  520. alta_adc adc_inst(
  521. .enb (!cfg_adc_en), // 使能来自cfg
  522. .sclk (sclk), // 分频时钟来自cfg配置
  523. .insel(chnl_sel), // 通道来自cfg配置
  524. .stop (stop),
  525. .db (adc_db),
  526. .eoc (adc_eoc)
  527. );
  528. endmodule
  529. // ==============================================
  530. // apb_dac 模块
  531. // ==============================================
  532. module apb_dac (
  533. input stop,
  534. output dma_req,
  535. input dma_clr,
  536. input apb_clock,
  537. input apb_resetn,
  538. input apb_psel,
  539. input apb_penable,
  540. input apb_pwrite,
  541. input [11:0] apb_paddr,
  542. input [31:0] apb_pwdata,
  543. output [31:0] apb_prdata,
  544. input dac_en, // 来自 CFG
  545. input dac_run, // 来自 CFG
  546. input [1:0] wave_type, // 来自 CFG
  547. input [9:0] max_vol, // 来自 CFG
  548. input [9:0] min_vol, // 来自 CFG
  549. input [31:0] frequency, // 来自 CFG
  550. input [7:0] duty_cycle // 来自 CFG
  551. );
  552. assign dma_req = 1'b0;
  553. assign apb_prdata = 32'd0;
  554. // ------------------- DDS 相位累加器(核心,只有加法)-------------------
  555. reg [31:0] phase_acc;
  556. always @(posedge apb_clock or negedge apb_resetn) begin
  557. if (!apb_resetn) begin
  558. phase_acc <= 32'd0;
  559. end else begin
  560. if (!dac_en || !dac_run) begin
  561. phase_acc <= 32'd0;
  562. end
  563. else begin
  564. phase_acc <= phase_acc + frequency;
  565. end
  566. end
  567. end
  568. wire [9:0] phase_comb = phase_acc[31:22]; // 10 位相位(组合)
  569. // // ========== 正弦查找表 ROM(组合读取) ==========
  570. (* ram_style = "distributed" *) // 强制综合为分布式 RAM,允许组合读出
  571. reg [9:0] sine_rom [0:1023];
  572. //(* ram_style = "block" *) reg [9:0] sine_rom [0:1023];
  573. initial begin
  574. $readmemh("sine.hex", sine_rom);
  575. end
  576. // // 组合读取:用 phase_r 作为地址直接出数据
  577. wire [9:0] sin_raw;
  578. assign sin_raw = sine_rom[phase_r];
  579. // ---------- 同步所有参与运算的信号 ----------
  580. // 目的:让 max_vol, min_vol, phase 在时钟沿后稳定,消除输入跳变引起的毛刺
  581. reg [9:0] max_vol_r, min_vol_r;
  582. reg [9:0] phase_r;
  583. reg phase_msb_r; // phase_acc[31] 用于方波
  584. always @(posedge apb_clock) begin
  585. max_vol_r <= max_vol;
  586. min_vol_r <= min_vol;
  587. phase_r <= phase_comb;
  588. phase_msb_r <= phase_acc[31];
  589. end
  590. // ---------- 组合逻辑:波形计算(纯组合,无毛刺输入)----------
  591. reg [9:0] wave_data_comb;
  592. reg [9:0] diff;
  593. reg [19:0] mult;
  594. reg [9:0] step;
  595. always @(*) begin
  596. // 使用寄存后的稳定值进行计算
  597. diff = max_vol_r - min_vol_r;
  598. case(wave_type)
  599. 2'b00: begin // 方波
  600. wave_data_comb = (phase_msb_r == 1'b0) ? max_vol_r : min_vol_r;
  601. end
  602. 2'b01: begin // 正弦波(查表 + 幅度缩放)
  603. mult = diff * sin_raw; // sin_raw 为 0~1023,中心 512
  604. step = mult >> 10; // 除以 1024
  605. wave_data_comb = min_vol_r + step;
  606. end
  607. 2'b10: begin // 三角波
  608. if (phase_r[9] == 1'b0) begin
  609. // 上升支:phase 0~511
  610. mult = diff * phase_r[8:0];
  611. step = mult >> 9;
  612. wave_data_comb = min_vol_r + step;
  613. end else begin
  614. // 下降支:phase 512~1023,phase_r[8:0] 实际等于 phase-512
  615. mult = diff * phase_r[8:0];
  616. step = mult >> 9;
  617. // 理论上 step <= diff,这里加个安全钳位
  618. wave_data_comb = (max_vol_r > step) ? (max_vol_r - step) : min_vol_r;
  619. end
  620. end
  621. 2'b11: begin // 锯齿波
  622. mult = diff * phase_r;
  623. step = mult >> 10; // 除以 1024,近似斜坡
  624. wave_data_comb = min_vol_r + step;
  625. end
  626. default: wave_data_comb = 10'd0;
  627. endcase
  628. end
  629. // ------------------------------
  630. // 关键:完全对齐官方极性
  631. // ------------------------------
  632. wire dac_dout;
  633. alta_dac dac_inst(
  634. .enb (!dac_en), // 低有效
  635. .bufenb (!dac_en), // 低有效 (用dac_en控制即可)
  636. .din (wave_data_comb), // 波形数据
  637. .stop (stop),
  638. .dout (dac_dout)
  639. );
  640. endmodule