HierarchyFilesModulesSignalsTasksFunctionsHelp
//
// File:   fft_sample.v
// Date:   10-Nov-05
// Author: I. Chuang <ichuang@mit.edu>;
//
// Demonstration of the Xilinx FFT module on data from an ADC.
//
// A 256-point, 8-bit discrete fourier transform is performed continuously
// on an incoming buffer of data, and the results are processed and 
// graphically displayed in a 256x256 window in a VGA display.
//
// This specific demo uses the Digilent ADC peripheral module,
// which has two ADCS7476 chips.  See http://www.digilentinc.com
//
// Connect the board as follows:
//
// CS  = User 3 D3 (user3[3])
// D0  = User 3 D2 (user3[2])
// D1  = User 3 D1 (user3[1])
// CLK = User 3 D0 (user3[0])
// VCC = 3.3V
//
// The FFT transform is done on the data in channel D0.
//
// The eight switches are used to set the FFT scaling factors, which are
// used to ensure the FFT does not overflow at any stage internal to the
// computation.  One reasonable starting point is 8'b0110_0110, if the
// ADC input is driven full range (0 to 3.3V swing sinusoid input).
//
// Note that the FFT produces two's complement output, and that the outputs
// give the real and imaginary part of the FFT.  A more useful output
// is the magnitude, which gives the power spectrum.  Here, we simply
// compute the sum of squares of the real and imaginary output values
// (and skip the square root).
//
// Also note that no input filtering is done, and thus there are 
// significant aliasing problems.  The input data should be filtered to
// cut off frequencies higher than the inverse of the sampling window
// size (here, 256 points).
//
// This example uses vga_graph2_buf, which produces a 256 x 256 window
// graph of two channels.
//
// Button 0 selects between FFT display and ADC value display
// Button 3 selects the test color bar display
// The enter button is reset.

`include "vga_sync.v"
`include "debounce.v"
`include "display_16hex.v"
`include "adc_driver.v"
`include "vga_graph2_buf.v"
`include "fft_256pt_8bit.v"
`include "math_8bit_mult.v"
`include "twos2off.v"

module fft_sampleIndex(
    beep, audio_reset_b, ac97_sdata_out, ac97_sdata_in, ac97_synch,
	       ac97_bit_clock,
	       
	       vga_out_red, vga_out_green, vga_out_blue, vga_out_sync_b,
	       vga_out_blank_b, vga_out_pixel_clock, vga_out_hsync,
	       vga_out_vsync,

	       tv_out_ycrcb, tv_out_reset_b, tv_out_clock, tv_out_i2c_clock,
	       tv_out_i2c_data, tv_out_pal_ntsc, tv_out_hsync_b,
	       tv_out_vsync_b, tv_out_blank_b, tv_out_subcar_reset,

	       tv_in_ycrcb, tv_in_data_valid, tv_in_line_clock1,
	       tv_in_line_clock2, tv_in_aef, tv_in_hff, tv_in_aff,
	       tv_in_i2c_clock, tv_in_i2c_data, tv_in_fifo_read,
	       tv_in_fifo_clock, tv_in_iso, tv_in_reset_b, tv_in_clock,

	       ram0_data, ram0_address, ram0_adv_ld, ram0_clk, ram0_cen_b,
	       ram0_ce_b, ram0_oe_b, ram0_we_b, ram0_bwe_b, 

	       ram1_data, ram1_address, ram1_adv_ld, ram1_clk, ram1_cen_b,
	       ram1_ce_b, ram1_oe_b, ram1_we_b, ram1_bwe_b,

	       clock_feedback_out, clock_feedback_in,

	       flash_data, flash_address, flash_ce_b, flash_oe_b, flash_we_b,
	       flash_reset_b, flash_sts, flash_byte_b,

	       rs232_txd, rs232_rxd, rs232_rts, rs232_cts,

	       mouse_clock, mouse_data, keyboard_clock, keyboard_data,

	       clock_27mhz, clock1, clock2,

	       disp_blank, disp_data_out, disp_clock, disp_rs, disp_ce_b,
	       disp_reset_b, disp_data_in,

	       button0, button1, button2, button3, button_enter, button_right,
	       button_left, button_down, button_up,

	       switch,

	       led,
	       
	       user1, user2, user3, user4,
	       
	       daughtercard,

	       systemace_data, systemace_address, systemace_ce_b,
	       systemace_we_b, systemace_oe_b, systemace_irq, systemace_mpbrdy,
	       
	       analyzer1_data, analyzer1_clock,
 	       analyzer2_data, analyzer2_clock,
 	       analyzer3_data, analyzer3_clock,
 	       analyzer4_data, analyzer4_clock
			);

   output beep, audio_reset_b, ac97_synch, ac97_sdata_out;
   input  ac97_bit_clock, ac97_sdata_in;
   
   output [7:0] vga_out_red, vga_out_green, vga_out_blue;
   output vga_out_sync_b, vga_out_blank_b, vga_out_pixel_clock,
	  vga_out_hsync, vga_out_vsync;

   output [9:0] tv_out_ycrcb;
   output tv_out_reset_b, tv_out_clock, tv_out_i2c_clock, tv_out_i2c_data,
	  tv_out_pal_ntsc, tv_out_hsync_b, tv_out_vsync_b, tv_out_blank_b,
	  tv_out_subcar_reset;
   
   input  [19:0] tv_in_ycrcb;
   input  tv_in_data_valid, tv_in_line_clock1, tv_in_line_clock2, tv_in_aef,
	  tv_in_hff, tv_in_aff;
   output tv_in_i2c_clock, tv_in_fifo_read, tv_in_fifo_clock, tv_in_iso,
	  tv_in_reset_b, tv_in_clock;
   inout  tv_in_i2c_data;
        
   inout  [35:0] ram0_data;
   output [18:0] ram0_address;
   output ram0_adv_ld, ram0_clk, ram0_cen_b, ram0_ce_b, ram0_oe_b, ram0_we_b;
   output [3:0] ram0_bwe_b;
   
   inout  [35:0] ram1_data;
   output [18:0] ram1_address;
   output ram1_adv_ld, ram1_clk, ram1_cen_b, ram1_ce_b, ram1_oe_b, ram1_we_b;
   output [3:0] ram1_bwe_b;

   input  clock_feedback_in;
   output clock_feedback_out;
   
   inout  [15:0] flash_data;
   output [23:0] flash_address;
   output flash_ce_b, flash_oe_b, flash_we_b, flash_reset_b, flash_byte_b;
   input  flash_sts;
   
   output rs232_txd, rs232_rts;
   input  rs232_rxd, rs232_cts;

   inout  mouse_clock, mouse_data;
   //input  mouse_clock, mouse_data;
   input  keyboard_clock, keyboard_data;

   input  clock_27mhz, clock1, clock2;

   output disp_blank, disp_clock, disp_rs, disp_ce_b, disp_reset_b;  
   input  disp_data_in;
   output  disp_data_out;
   
   input  button0, button1, button2, button3, button_enter, button_right,
	  button_left, button_down, button_up;
   input  [7:0] switch;
   output [7:0] led;

   inout [31:0] user1, user2, user3, user4;
   
   inout [43:0] daughtercard;

   inout  [15:0] systemace_data;
   output [6:0]  systemace_address;
   output systemace_ce_b, systemace_we_b, systemace_oe_b;
   input  systemace_irq, systemace_mpbrdy;

   output [15:0] analyzer1_data, analyzer2_data, analyzer3_data, 
		 analyzer4_data;
   output analyzer1_clock, analyzer2_clock, analyzer3_clock, analyzer4_clock;

   ////////////////////////////////////////////////////////////////////////////
   //
   // I/O Assignments
   //
   ////////////////////////////////////////////////////////////////////////////
   
   // Audio Input and Output
   assign beep= 1'b0;
   assign audio_reset_b = 1'b0;
   assign ac97_synch = 1'b0;
   assign ac97_sdata_out = 1'b0;

   // ac97_sdata_in is an input

   // VGA Output
//   assign vga_out_red = 10'h0;
//   assign vga_out_green = 10'h0;
//   assign vga_out_blue = 10'h0;
   assign vga_out_sync_b = 1'b1;
//   assign vga_out_blank_b = 1'b1;
//   assign vga_out_pixel_clock = 1'b0;
//   assign vga_out_hsync = 1'b0;
//   assign vga_out_vsync = 1'b0;

   // Video Output
   assign tv_out_ycrcb = 10'h0;
   assign tv_out_reset_b = 1'b0;
   assign tv_out_clock = 1'b0;
   assign tv_out_i2c_clock = 1'b0;
   assign tv_out_i2c_data = 1'b0;
   assign tv_out_pal_ntsc = 1'b0;
   assign tv_out_hsync_b = 1'b1;
   assign tv_out_vsync_b = 1'b1;
   assign tv_out_blank_b = 1'b1;
   assign tv_out_subcar_reset = 1'b0;
   
   // Video Input
   assign tv_in_i2c_clock = 1'b0;
   assign tv_in_fifo_read = 1'b0;
   assign tv_in_fifo_clock = 1'b0;
   assign tv_in_iso = 1'b0;
   assign tv_in_reset_b = 1'b0;
   assign tv_in_clock = 1'b0;
   assign tv_in_i2c_data = 1'bZ;
   // tv_in_ycrcb, tv_in_data_valid, tv_in_line_clock1, tv_in_line_clock2, 
   // tv_in_aef, tv_in_hff, and tv_in_aff are inputs
   
   // SRAMs
   assign ram0_data = 36'hZ;
   assign ram0_address = 19'h0;
   assign ram0_adv_ld = 1'b0;
   assign ram0_clk = 1'b0;
   assign ram0_cen_b = 1'b1;
   assign ram0_ce_b = 1'b1;
   assign ram0_oe_b = 1'b1;
   assign ram0_we_b = 1'b1;
   assign ram0_bwe_b = 4'hF;
   assign ram1_data = 36'hZ; 
   assign ram1_address = 19'h0;
   assign ram1_adv_ld = 1'b0;
   assign ram1_clk = 1'b0;
   assign ram1_cen_b = 1'b1;
   assign ram1_ce_b = 1'b1;
   assign ram1_oe_b = 1'b1;
   assign ram1_we_b = 1'b1;
   assign ram1_bwe_b = 4'hF;
   assign clock_feedback_out = 1'b0;
   // clock_feedback_in is an input
   
   // Flash ROM
   assign flash_data = 16'hZ;
   assign flash_address = 24'h0;
   assign flash_ce_b = 1'b1;
   assign flash_oe_b = 1'b1;
   assign flash_we_b = 1'b1;
   assign flash_reset_b = 1'b0;
   assign flash_byte_b = 1'b1;
   // flash_sts is an input

   // RS-232 Interface
   assign rs232_txd = 1'b1;
   assign rs232_rts = 1'b1;
   // rs232_rxd and rs232_cts are inputs

   // PS/2 Ports
   // mouse_clock, mouse_data, keyboard_clock, and keyboard_data are inputs

   // LED Displays
/*
   assign disp_blank = 1'b1;
   assign disp_clock = 1'b0;
   assign disp_rs = 1'b0;
   assign disp_ce_b = 1'b1;
   assign disp_reset_b = 1'b0;
   assign disp_data_out = 1'b0;
*/
   // disp_data_in is an input

   // Buttons, Switches, and Individual LEDs
   //lab3 assign led = 8'hFF;
   // button0, button1, button2, button3, button_enter, button_right,
   // button_left, button_down, button_up, and switches are inputs

   // User I/Os
   assign user1 = 32'hZ;
   assign user2 = 32'hZ;
   assign user3 = 32'hZ;
   assign user4 = 32'hZ;

   // Daughtercard Connectors
   assign daughtercard = 44'hZ;

   // SystemACE Microprocessor Port
   assign systemace_data = 16'hZ;
   assign systemace_address = 7'h0;
   assign systemace_ce_b = 1'b1;
   assign systemace_we_b = 1'b1;
   assign systemace_oe_b = 1'b1;
   // systemace_irq and systemace_mpbrdy are inputs

   // Logic Analyzer
   assign analyzer1_data = 16'h0;
   assign analyzer1_clock = 1'b1;
   assign analyzer2_data = 16'h0;
   assign analyzer2_clock = 1'b1;
   assign analyzer3_data = 16'h0;
   assign analyzer3_clock = 1'b1;
   assign analyzer4_data = 16'h0;
   assign analyzer4_clock = 1'b1;

   // use FPGA's digital clock manager to produce a 50 Mhz clock from 27 Mhz
   // actual frequency: 49.85 MHz
   wire clock_50mhz_unbuf,clock_50MHz;
   DCM vclk1(.CLKIN(clock_27mhz),.CLKFX(clock_50mhz_unbuf));
   // synthesis attribute CLKFX_DIVIDE of vclk1 is 13
   // synthesis attribute CLKFX_MULTIPLY of vclk1 is 24
   // synthesis attribute CLK_FEEDBACK of vclk1 is NONE
   // synthesis attribute CLKIN_PERIOD of vclk1 is 37
   BUFG vclk2(.O(clock_50MHz),.I(clock_50mhz_unbuf));

   ////////////////////////////////////////
   // The fft example

   wire   clk = clock_50MHz;

   wire power_on_reset;
   SRL16 reset_sr (.D(1'b0), .CLK(clk), .Q(power_on_reset),
		   .A0(1'b1), .A1(1'b1), .A2(1'b1), .A3(1'b1));
   defparam reset_sr.INIT = 16'hFFFF;

   wire user_reset;
   debounce dbreset(1'b0,clk,~button_enter,user_reset);

   wire reset = power_on_reset | user_reset;

   // generate synchronous clock for DSP system: 806.45 kHz
   reg [5:0] dcount;
   wire      clk_dsp = (dcount==61) ? 1 : 0;
   always @(posedge clk) dcount <= clk_dsp ? 0 : dcount+1;

   // adc driver

   wire [11:0] adc_v0, adc_v1;
   wire        adc_rdy;
   wire        adc_cs_b, adc_clk, adc_data0, adc_data1;

   assign      user3[0] = adc_clk;
   assign      user3[1] = 1'hZ;
   assign      user3[2] = 1'hZ;
   assign      user3[3] = adc_cs_b;

   assign      adc_data0 = user3[2];
   assign      adc_data1 = user3[1];

   adc_driver ad1(clk,adc_cs_b,adc_clk,adc_data0,adc_data1,adc_v0,
		  adc_v1,adc_rdy);

   // fft
   //
   // Be careful: the FFT module expects data input and output all in two's 
   // complement format.

   // note that a good value to set the scale to is 8'b1010_1011

   reg [7:0]   xn_re;
   wire [7:0]  xn_im;
   wire        fft_start;
   wire        fwd_inv = 1;
   wire        fwd_inv_we;	
   wire [7:0]  scale_sch = switch;	// wired to switches
   wire        scale_sch_we;
   wire [7:0]  xk_re,xk_im;
   wire [7:0]  xn_index, xk_index;
   wire        fft_ce = clk_dsp;	
   wire        fft_rfd;
   wire        fft_busy;
   wire        fft_dv;
   wire        fft_edone;
   wire        fft_done;

   fft_256pt_8bit fft1(xn_re,	// real data, input
		       xn_im,	// imaginary data, input
		       fft_start,	// start data loading & conversion, in
		       fwd_inv,		// forward or inverse, input
		       fwd_inv_we,	// write enable for fwd_inv, input
		       scale_sch,	// scaling schedule, input
		       scale_sch_we,	// write enable for scale_sch, input
		       fft_ce,		// clock enable
		       clk,		// system synchronous clock
		       xk_re,		// output real data
		       xk_im,		// output imaginary data
		       xn_index,	// index of input data (output)
		       xk_index,	// index of output data (output)
		       fft_rfd,		// ready for data, out
		       fft_busy,	// high while core is computing fft
		       fft_dv,		// data valid, output
		       fft_edone,	// early done strobe, output
		       fft_done);	// fft complete strobe, output

   // fft module initialization: simple sequencer
   // initclk = 0: nop, 1: load scale and fwd/inv, 3: start fft

   reg [1:0]   initclk;
   always @(posedge clk)
     initclk <= reset ? 0 : (((initclk<3) & clk_dsp) ? initclk + 1 : initclk);
   assign      fwd_inv_we = (initclk==2'd1);
   assign      fft_start = (initclk==2'd3);

   // reload scale factors when changed as well as at init time

   reg [7:0]   old_scale_sch;
   always @(posedge clk) old_scale_sch <= scale_sch;
   assign      scale_sch_we = initclk[0] | ~(scale_sch==old_scale_sch);

   // feed data to the FFT : be sure to convert to two's complement.
   // we assume data from ADC is centered around the mean.
   
   assign      xn_im = 8'b0;	// no imaginary valued data (for now)
   wire [3:0]  adc_scale = 4'd4;	// ADC is 12 bits; discard lower four
   wire [11:0] gdat = adc_v0;	// which channel of ADC to transform
   wire [11:0] pdat = (gdat >> adc_scale);
   wire [7:0]  vdat;		// two's complement voltage data to FFT
   offset_to_twos ott1(pdat[7:0],vdat);

   always @(posedge clk)	// register the data and feed to FFT
     xn_re <= clk_dsp ? vdat : xn_re;

   // compute sum of squares of FFT output real and imaginary parts
   // to get a power spectrum

   wire [15:0] re_sq, im_sq;
   math_8bit_mult m8m_signed1(clk,xk_re,xk_re,re_sq);
   math_8bit_mult m8m_signed2(clk,xk_im,xk_im,im_sq);

   wire [16:0] fft_out_sum_sq = re_sq + im_sq;

   // convert FFT outputs to shifted unsigned integer
   // wire [7:0]  fft_out_re, fft_out_im;
   // twos_to_offset tto1(xk_re,fft_out_re);
   // twos_to_offset tto2(xk_im,fft_out_im);

   // 640x480 VGA display
   wire [2:0] pixel;
   wire       blank;
   wire       pix_clk;
   wire [9:0] hcount, vcount;
   assign     vga_out_red = {8{pixel[0]}};
   assign     vga_out_green = {8{pixel[1]}};
   assign     vga_out_blue = {8{pixel[2]}};
   assign     vga_out_blank_b = ~blank;
   assign     vga_out_pixel_clock = pix_clk;	 // vga pixel clock
   
   vga_sync vga1(clk,vga_out_hsync,vga_out_vsync,hcount,vcount,pix_clk,blank);

   // video graph

   wire [2:0] gpix;
   wire [7:0] gdat1 = ~button0 ? adc_v0[11:4] : fft_out_sum_sq[15:8];
   wire [7:0] gdat2 = ~button0 ? adc_v1[11:4] : 8'b0;
  
   vga_graph2_buf vg1(reset,clk,pix_clk,hcount,vcount,gpix,
		      gdat1,gdat2,clk_dsp,fft_done,10'd190,10'd200);
   defparam   vg1.NX = 256;

   // cumulative video pixel

   wire       fpixel = (hcount==0 | hcount==639 | vcount==0 | vcount==479);
   wire [2:0] cumpix = {3{fpixel}} | gpix ;
   assign     pixel = (~button3 ? hcount[7:5] : cumpix) & ~{3{blank}};

   // debug
   assign      led = ~switch;
 
   wire [63:0] dispdata = {adc_v0,4'b0,adc_v1,4'b0,4'b0,4'b0,xn_re,
			   8'b0,scale_sch};
   display_16hex d1(reset, clk, dispdata,
		    disp_blank, disp_clock, disp_rs, disp_ce_b,
		    disp_reset_b, disp_data_out);
 
endmodule

HierarchyFilesModulesSignalsTasksFunctionsHelp

This page: Created:Thu Dec 8 21:40:41 2005
From: fft_sample.v

Verilog converted to html by v2html 7.30 (written by Costas Calamvokis).Help