⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 deci_poly.v

📁 一种由可编程逻辑器件集成的数字滤波器的设计
💻 V
字号:
module deci_poly (
		   clk,
		   clken,
		   reset,
		   x0,
		   result,
		   load_data
		 );
		
   parameter DATA_WIDTH = 9;
   parameter COEF_WIDTH = 12;
   parameter SHIFT_WIDTH = (DATA_WIDTH * 3);
   parameter MULT_ADD_WIDTH = DATA_WIDTH + COEF_WIDTH + 2;
   parameter OUTPUT_WIDTH = MULT_ADD_WIDTH + 3;

   input clk;
   input clken;
   input reset;
   input [DATA_WIDTH-1:0] x0;
   
   output [OUTPUT_WIDTH-1:0] result;
   output 		 		     load_data;
   
   reg [1:0] 	 			address;
   reg [2:0]     			pll_start;
   reg [2:0]     			pll_add_start;
   reg [DATA_WIDTH-1:0]    	data_d1;
   reg [OUTPUT_WIDTH-1:0]   accumulator_out;
   reg [OUTPUT_WIDTH-1:0]   result;
   reg [1:0]	 			cnt_data_rdy;
   reg   		 			load;
   reg [1:0]     			load_cnt;
   reg [OUTPUT_WIDTH-1:0]   mult_add_result;
   reg  				    load_data;
   
   wire 	     			clk1x, clk4x;
   wire [DATA_WIDTH-1:0] 	datab_0, datab_1, datab_2, datab_3;
   wire [COEF_WIDTH-1:0] 	rom_out0, rom_out1, rom_out2, rom_out3;
   wire   	     			rom_clken_w;
   wire			 			rom_clken;
   wire			 			locked;
   wire [SHIFT_WIDTH-1:0]	taps_w;
   wire [DATA_WIDTH-1:0]   	dataa_0, dataa_1, dataa_2, dataa_3;
   wire [OUTPUT_WIDTH-1:0]  accumulator_out_w; 
   wire [OUTPUT_WIDTH-1:0]  mult_add_out_w;
   wire [MULT_ADD_WIDTH-1:0]mult_add_result_w;
   wire		     			accumulator_reset;
   wire			 			address_reset;
   wire			 			clear_accum;
   wire		     			clear_address;
   wire			 			load_data_w;
   wire          			address_clken_w;
   wire			 			address_clken;
   wire	[OUTPUT_WIDTH-1:0]  accumulator_fd_bk;

   assign rom_clken_w = (pll_start == 3'b001) ? 1'b1 : 1'b0;
   assign rom_clken = locked;
   assign address_clken_w = (pll_add_start == 3'b001) ? 1'b1 : 1'b0;
   assign address_clken = locked;
   assign clear_address = (cnt_data_rdy == 2'b10 && load == 1'b1) ? 1'b1 : 1'b0;
   assign clear_accum = (cnt_data_rdy == 2'b10) ? 1'b1 : 1'b0;
   assign load_data_w = (load_cnt == 2'b10 && load == 1'b1) ? 1'b1 : 1'b0;

   assign dataa_0 = data_d1;
   assign dataa_1 = taps_w[DATA_WIDTH-1:0];
   assign dataa_2 = taps_w[2*DATA_WIDTH-1:DATA_WIDTH];
   assign dataa_3 = taps_w[SHIFT_WIDTH-1:2*DATA_WIDTH];
   assign mult_add_out_w[OUTPUT_WIDTH-1:MULT_ADD_WIDTH] = (mult_add_result_w[MULT_ADD_WIDTH-1] == 1'b1) ? 3'b111 : 3'b000;
   assign mult_add_out_w[MULT_ADD_WIDTH-1:0] = mult_add_result_w;
   assign accumulator_reset = reset || clear_accum;
   assign address_reset = reset || clear_address;
   assign accumulator_fd_bk = (accumulator_reset == 1'b1) ? 0 : accumulator_out_w;
   
 
   always @ (posedge clk4x) begin
       if (reset)
		 pll_start <= 0;
	   else if (rom_clken_w == 0 && locked == 1)
	     pll_start <= pll_start + 1;
	   else 
	     pll_start <= pll_start;
	end
	
	always @ (posedge clk4x) begin
       if (reset)
		 pll_add_start <= 0;
	   else if (address_clken_w == 0 && locked == 1)
	     pll_add_start <= pll_add_start + 1;
	   else 
	     pll_add_start <= pll_add_start;
	end
   
   always @ (posedge clk1x) begin
      if (reset )
           load <= 1'b0;
      else if ( locked )
           load <= 1'b1;
   end

   always @ (posedge clk4x) begin
      if (reset )
           load_data <= 0;
      else if ( load )
           load_data <= load_data_w;
   end
   

   always @ (posedge clk4x) begin
      if ( reset )
           load_cnt <= 0;
      else if ( load )
           load_cnt <= load_cnt + 1;
   end

   always @ (posedge clk4x) begin
      if (reset || address_reset) begin
      	  address <= 0;
		end
	  else if (load) begin
	 	  address <= address - 1;
	    end
   end 

   always @ (posedge clk4x) begin
      if (reset) 
         cnt_data_rdy <= 0;
      else if (load)
         cnt_data_rdy <= cnt_data_rdy + 1;
   end

   
   always @(posedge clk4x) begin
      if (reset) 
	 	  data_d1 <= 0;		
	  else if (rom_clken) 
	      data_d1 <= x0;
  end 

  always @ (posedge clk4x) begin
       if (reset) 
          mult_add_result <= 0;
       else if (rom_clken) 
		  mult_add_result <= mult_add_out_w;
	end
  
  always @ (posedge clk4x) begin
       if (reset) 
          accumulator_out <= 0;
       else if (rom_clken) 
		  accumulator_out <= accumulator_out_w;
	end

   always @(posedge clk1x) begin
      if (reset) 
	 	  result <= 0;		
	  else if (rom_clken)
	      result <= accumulator_out;
	end 


   pll	pll_inst (
		.inclk0 ( clk ),
		.pllena ( clken ),
		.c0 ( clk4x ),
		.c1 ( clk1x ),
		.locked ( locked )
		);
		
   shift_reg	shift_reg_inst (
	.shiftin ( data_d1 ),
	.clock ( clk4x ),
	.clken ( rom_clken ),
	.shiftout ( shiftout_sig ),
	.taps ( taps_w )
	);

   rom0 rom0 (
	    .address (address),
	    .clock (clk4x),
	    .clken (rom_clken),
	    .q (rom_out0)
	    );

  rom1 rom1 (
	    .address (address),
	    .clock (clk4x),
		.clken (rom_clken),
	    .q (rom_out1)
	    );

  rom2 rom2 (
	    .address (address),
	    .clock (clk4x),
		.clken (rom_clken),
	    .q (rom_out2)
	    );

  rom3 rom3 (
	    .address (address),
	    .clock (clk4x),
		.clken (rom_clken),
	    .q (rom_out3)
	    );

   mult_add mult_add (
		.clock1 (clk4x),
		.ena1 (rom_clken),
		.aclr3 (reset),
		.dataa_0 (data_d1),
		.dataa_1 (dataa_1),
		.dataa_2 (dataa_2),
		.dataa_3 (dataa_3),
		.datab_0 (rom_out0),
		.datab_1 (rom_out1),
		.datab_2 (rom_out2),
		.datab_3 (rom_out3),
		.result (mult_add_result_w)
    );

   accumulator	accumulator_inst (
		.dataa ( mult_add_result ),
		.datab ( accumulator_fd_bk ),
		.clock ( clk4x ),
		.aclr (reset),
		.clken ( rom_clken),
		.result ( accumulator_out_w ),
		.cout (  ),
		.overflow (  )
	);

   
   endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -