📄 samp_gen.v
字号:
//-----------------------------------------------------------------------------// // Copyright (c) 2009 Xilinx Inc.//// Project : Programmable Wave Generator// Module : samp_gen.v// Parent : wave_gen// Children : meta_harden//// Description: // This generates the output samples of the wave generator.//// When enabled via the samp_gen_go_clk_rx signal, which is either pulsed// for 3 clocks or continuously asserted, it will cycle through all nsamp// samples at a rate of one sample every 'speed' cycles of the prescaled// clock (clk_samp), which is synchronous to clk_tx, but asserted only one// out of every 'prescale' cycles.//// The samp_gen_go_clk_rx signal must be synchronized to clk_tx, and held// until the next rising edge of clk_samp (as indicated by the en_clk_samp)// signal.//// Parameters:// NSAMP_WID: Width of nsamp - since its coded naturally, must// be one bit larger (to code 2**NSAMP_WID)//// Local Parameters://// Notes : //// Multicycle and False Paths// Most of this module runs on clk_samp, which is a decimated clock. All// paths from FFs on clk_samp to FFs on clk_samp are multi-cycle. Since// prescale cannot be less than 32, these paths should all be declared as// 32 cycle MCPs.//// The metaharden module used within also requires a timing exception.//`timescale 1ns/1psmodule samp_gen #( parameter NSAMP_WID = 10) ( // Write side inputs input clk_tx, // Clock input input rst_clk_tx, // Active HIGH reset - synchronous to clk_tx input clk_samp, // Clock input input rst_clk_samp, // Active HIGH reset - synchronous to clk_samp input en_clk_samp, // Last clk_tx phase of clk_samp input samp_gen_go_clk_rx, // Starts the sample gen - on clk_rx input [NSAMP_WID:0] nsamp_clk_tx, // Current value of nsamp input [15:0] spd_clk_tx, // Current value of speed output [NSAMP_WID-1:0] samp_gen_samp_ram_addr, // Address to sample RAM input [15:0] samp_gen_samp_ram_dout, // Data returned from samp RAM output [15:0] samp, // Sample output output reg samp_val, // New sample is available output reg [7:0] led_o // Upper bits of samples sent to LEDs);//***************************************************************************// Parameter definitions//***************************************************************************//***************************************************************************// Reg and Wire declarations//*************************************************************************** wire samp_gen_go_clk_tx; // Meta_hardened reg samp_gen_go_hold; // Held until next clk_samp reg active; // Set when currently active reg [15:0] speed_cnt; // Counts speed-1 to 0 reg [NSAMP_WID-1:0] samp_cnt; // Counts from 0 to nsamp-1 wire start_samp_gen; // Signal that indicates the samp_gen shoud // start - a combination of the // synchronized samp_gen_go_clk_tx and // samp_gen_go_hold wire restart_samp_gen; // Indicates that we are completing one // sweep and need to immediately start // a new one wire speed_cnt_done; // The speed counter has reached 0 // Time for next sample wire samp_cnt_done; // On the last sample reg doing_read; // The RAM is doing a read on this clock reg read_done; // This is the cycle that the read is done // Therefore the data is on the RAM output reg [15:0] samp_reg; // Register for holding captured sample //***************************************************************************// Code//*************************************************************************** // Metastability harden samp_gen_go to the clk_tx domain meta_harden meta_harden_samp_gen_go_i0 ( .clk_dst (clk_tx), .rst_dst (rst_clk_tx), .signal_src (samp_gen_go_clk_rx), .signal_dst (samp_gen_go_clk_tx) ); // Capture and hold samp_gen_go always @(posedge clk_tx) begin if (rst_clk_tx) begin samp_gen_go_hold <= #1 1'b0; end else begin if (samp_gen_go_hold) begin if (en_clk_samp && !samp_gen_go_clk_tx) begin samp_gen_go_hold <= #1 1'b0; end end else begin if (samp_gen_go_clk_tx && !en_clk_samp) begin samp_gen_go_hold <= #1 1'b1; end end end // if rst_clk_tx end // always assign start_samp_gen = samp_gen_go_clk_tx || samp_gen_go_hold; assign restart_samp_gen = (speed_cnt_done && samp_cnt_done && start_samp_gen); // Track the current state of the sample generator. It is either active, or // inactive always @(posedge clk_samp) begin if (rst_clk_samp) begin active <= 1'b0; end else begin if (!active) begin if (start_samp_gen) begin active <= 1'b1; end // Start while inactive end else // we are currently active begin // We go inactive if we are doing the last count, and we don't // need to restart if (samp_cnt_done && speed_cnt_done && !start_samp_gen) begin active <= 1'b0; end end end // if rst end // always // Generate speed_cnt. We are supposed to generate one sample every // spd_clk_tx cycles, thus we need a counter. This counter counts form // spd_clk_tx-1 down to 0 for each sample. If spd_clk_tx is 1, then this // will count (correctly) from 0 to 0 (i.e. one iteration) always @(posedge clk_samp) begin if (rst_clk_samp) begin speed_cnt <= 16'h0000; end else begin if (speed_cnt != 16'h0000) begin speed_cnt <= speed_cnt - 1'b1; end else if ((active && !samp_cnt_done) || start_samp_gen) begin // speed_cnt is 0, so we have "completed" this sample... // Restart the counter to count the next sample, as long as there is // one. // There is a new sample if this is not the last sample. We also have // to restart if it IS the last sample, but we are being asked to // restart a new sweep right away (which will be the case in // "Continuous" mode *C. speed_cnt <= spd_clk_tx - 1'b1; end end // if rst_clk_samp end // always assign speed_cnt_done = (speed_cnt == 16'h0000); // Track which sample we are sending - count from 0 to nsamp-1 always @(posedge clk_samp) begin if (rst_clk_samp) begin samp_cnt <= {NSAMP_WID{1'b0}}; end else begin if ((!active && start_samp_gen) || restart_samp_gen) // Start a new sweep begin samp_cnt <= {NSAMP_WID{1'b0}}; // Start at 0 end else if (active && speed_cnt_done && !samp_cnt_done) begin // speed_cnt is expiring, and this is not the last sample - get the // next one. If this is the last one, and we are re-starting, we will // have loaded it via the condition above samp_cnt <= samp_cnt + 1'b1; end end // if rst_clk_samp end // always assign samp_cnt_done = (samp_cnt == nsamp_clk_tx - 1'b1); assign samp_gen_samp_ram_addr = samp_cnt; // Generate doing_read - this is the clock where the address to the RAM is // valid, and hence the RAM will have the correct data on the next clock always @(posedge clk_samp) begin if (rst_clk_samp) begin doing_read <= 1'b0; end else begin // This signal is asserted on the clock after samp_gen starts, // or the clock after speed_cnt_done is asserted, unless this we // have already done the last sample, and we are not restarting. if ((!active && start_samp_gen) || (active && speed_cnt_done && (!samp_cnt_done || restart_samp_gen) ) ) begin doing_read <= 1'b1; end else begin doing_read <= 1'b0; end end // if rst_clk_samp end // always // Generate the sample outputs always @(posedge clk_samp) begin if (rst_clk_samp) begin read_done <= 1'b0; samp_reg <= 1'b0; samp_val <= 1'b0; led_o <= 8'b0; end else begin read_done <= doing_read; samp_val <= read_done; if (read_done) begin samp_reg <= samp_gen_samp_ram_dout; end led_o <= samp_reg[15:8]; end // if rst_clk_rx end // always assign samp = samp_reg;endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -