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

📄 lp_tx.v

📁 altera fpga 和ts201的linkport接口设计
💻 V
字号:
// ================================================================================
// (c) 2003 Altera Corporation. All rights reserved.
// Altera products are protected under numerous U.S. and foreign patents, maskwork
// rights, copyrights and other intellectual property laws.
// 
// This reference design file, and your use thereof, is subject to and governed
// by the terms and conditions of the applicable Altera Reference Design License
// Agreement (either as signed by you, agreed by you upon download or as a
// "click-through" agreement upon installation andor found at www.altera.com).
// By using this reference design file, you indicate your acceptance of such terms
// and conditions between you and Altera Corporation.  In the event that you do
// not agree with such terms and conditions, you may not use the reference design
// file and please promptly destroy any copies you have made.
// 
// This reference design file is being provided on an "as-is" basis and as an
// accommodation and therefore all warranties, representations or guarantees of
// any kind (whether express, implied or statutory) including, without limitation,
// warranties of merchantability, non-infringement, or fitness for a particular
// purpose, are specifically disclaimed.  By making this reference design file
// available, Altera expressly does not recommend, suggest or require that this
// reference design file be used in combination with any other product not
// provided by Altera.
// ================================================================================

module lp_tx (clk, 
	      clk270,   
	      clk4,     
	      rst_n,

	      tvere, //校验字节使能
	      
	      tx_wr,
	      tx_wdata,
	      tx_wrused,
	      tx_wrfull,
	      
	      clk_out,
	      data_out,
	      acki,
	      bcmpo_n
	      );

  input clk;
  input clk270;	// 270 deg phase shifted clock
  input clk4;	// half rate clock
  input rst_n;

  input tvere;	// Tx verification byte enable
  
  input tx_wr;
  input [32:0] tx_wdata;
  output [3:0] tx_wrused;
  output       tx_wrfull;

  output       clk_out;
  output [3:0] data_out;
  input        acki;
  output       bcmpo_n;

  parameter    DEVICE	= "Cyclone II";
  
  wire [3:0]   tx_wrused;
  wire 	       tx_wrfull;
  
  reg 	       tx_rd;
  wire [32:0]  tx_data;
  wire [3:0]   tx_rd_used;
  wire [3:0]   data_out;

  dcfifo tx_fifo (
		  .aclr		(~rst_n),
		  .wrclk	(clk4),
		  .wrreq	(tx_wr),
		  .data		(tx_wdata),
		  .wrusedw	(tx_wrused),
		  .wrfull	(tx_wrfull),
		  
		  .rdclk	(clk4),
		  .rdreq	(tx_rd),
		  .q		(tx_data),
		  .rdusedw	(tx_rd_used),
		  .rdempty	()
		  );
  defparam     
	       tx_fifo.intended_device_family = DEVICE,
	       tx_fifo.lpm_width = 33,
	       tx_fifo.lpm_numwords = 16,
	       tx_fifo.lpm_widthu = 4,
	       tx_fifo.clocks_are_synchronized = "TRUE",
	       tx_fifo.lpm_type = "dcfifo",
	       tx_fifo.lpm_showahead = "OFF",
	       tx_fifo.overflow_checking = "OFF",
	       tx_fifo.underflow_checking = "OFF",
	       tx_fifo.use_eab = "ON",
	       tx_fifo.add_ram_output_register = "ON",
	       tx_fifo.lpm_hint = "RAM_BLOCK_TYPE=AUTO";

  // Synchronize acki to local clock
  reg 	       acki_sync1;
  reg 	       acki_sync;
  always @(posedge clk4 or negedge rst_n)
    if (~rst_n)
    begin
      acki_sync1 <= 1'b0;
      acki_sync <= 1'b0;
    end
    else
    begin
      acki_sync1 <= acki;
      acki_sync <= acki_sync1;
    end
  
  reg [6:0] 	tx_state;
  // One hot coded for fast decoding
  always @(posedge clk4 or negedge rst_n)
    if (~rst_n)
      tx_state <= 7'b1;//11'b1
    else
    begin
      tx_state[0] <= tx_state[0] & ~((tx_rd_used >= 4'h4) & acki_sync)
		      | tx_state[5] & ~tvere & ~tx_rd & ~((tx_rd_used >= 4'h4) & acki_sync)
		      | tx_state[6] & ~tx_rd & ~((tx_rd_used >= 4'h4) & acki_sync);
      tx_state[1] <= tx_state[0] & (tx_rd_used >= 4'h4) & acki_sync
		      | tx_state[5] & ~tvere & ~tx_rd & (tx_rd_used >= 4'h4) & acki_sync
		      | tx_state[6] & ~tx_rd & (tx_rd_used >= 4'h4) & acki_sync;
      tx_state[2] <= tx_state[1]
		      | tx_state[5] & ~tvere & tx_rd
		      | tx_state[6] & tx_rd;
      tx_state[5:3] <= tx_state[4:2];
      tx_state[6] <= tx_state[5] & tvere;
    end      
 
  always @(posedge clk4 or negedge rst_n)
    if (~rst_n)
      tx_rd <= 1'b0;
    else
      tx_rd <= tx_state[0] & (tx_rd_used >= 4'h4) & acki_sync
	     | ~tvere & tx_state[4] & (tx_rd_used >= 4'h4) & acki_sync
	     | ~tvere & tx_rd & tx_state[5]
	     | ~tvere & ~tx_rd & tx_state[5] & (tx_rd_used >= 4'h4) & acki_sync
	     | tvere & tx_state[5] & (tx_rd_used >= 4'h4) & acki_sync
	     | tvere & tx_rd & tx_state[6]
	     | tvere & ~tx_rd & tx_state[6] & (tx_rd_used >= 4'h4) & acki_sync
	     | tx_state[1] | tx_state[2] | tx_state[3];

  reg 	    clk_en;
  reg 	    clk_en_r;
  reg 	    clk_en_rr;
  reg 	    clk_en_rrr;

  reg [1:0] edges_dly;
  always @(posedge clk or negedge rst_n)
    if (~rst_n)
      edges_dly <= 2'b0;
    else if (tx_state[2])
      edges_dly <= edges_dly + 2'b1;
    else
      edges_dly <= 2'b0;
  
  reg [15:0]    edges;
  // One hot coded for fast decoding
  always @(posedge clk or negedge rst_n)
    if (~rst_n)
      edges <= 16'b0;
    else
    begin
      if (edges_dly == 2'b11)
	edges[0] <= 1'b1;
      else
	edges[0] <= 1'b0;
      edges[15:1] <= edges[14:0];
    end

  reg 	       load_ddr_data_in;
  always @(posedge clk270 or negedge rst_n)
    if (~rst_n)
      load_ddr_data_in <= 1'b0;
    else
      load_ddr_data_in <= (edges_dly == 2'b10)
			  | edges[2] | edges[6] | edges[10];

  reg 	       bcmpo_n;
  always @(posedge clk4 or negedge rst_n)
    if (~rst_n)
      bcmpo_n <= 1'b1;
    else if (~tvere)
    begin
      if (tx_state[2] | tx_state[0])
	bcmpo_n <= 1'b1;
      else if (tx_state[3] & tx_data[32])
	bcmpo_n <= 1'b0;
    end
    else
    begin
      if (tx_state[6])
	bcmpo_n <= 1'b1;
      else if (tx_state[3] & tx_data[32])
	bcmpo_n <= 1'b0;
    end
      
  wire [7:0] cksum;
  reg [7:0]  cksum_reg;
  reg 	     load_cksum;
  always @(posedge clk270 or negedge rst_n)
    if (~rst_n)
      load_cksum <= 1'b0;
    else
      load_cksum <= tvere & edges[15];
  
  reg [31:0] 	ddr_data_in;
  always @(posedge clk270 or negedge rst_n)
    if (~rst_n)
      ddr_data_in[31:8] <= 24'b0;
    else if (load_ddr_data_in)
      ddr_data_in[31:8] <= tx_data[31:8];
    else
      ddr_data_in[31:8] <= {8'b0, ddr_data_in[31:16]};

  always @(posedge clk270 or negedge rst_n)
    if (~rst_n)
      ddr_data_in[7:0] <= 8'b0;
    else if (load_ddr_data_in)
      ddr_data_in[7:0] <= tx_data[7:0];
    else
      ddr_data_in[7:0] <= ddr_data_in[15:8];

  reg [7:0] 	ddr_data;
  always @(posedge clk270 or negedge rst_n)
    if (~rst_n)
      ddr_data <= 8'b0;
    else if (load_cksum)
      ddr_data <= cksum_reg;
    else
      ddr_data <= ddr_data_in[7:0];
  
 altddio_out lp_tx_data_3 (
			  .datain_h	(ddr_data[3]),
			  .datain_l	(ddr_data[7]),
			  .outclock	(clk270),
			  .aclr		(~rst_n),
			  .dataout	(data_out[3])
			  );
  defparam 	
		lp_tx_data_3.width = 1,
		lp_tx_data_3.intended_device_family = DEVICE,
		lp_tx_data_3.oe_reg = "UNUSED",
		lp_tx_data_3.extend_oe_disable = "UNUSED",
		lp_tx_data_3.lpm_type = "altddio_out";

  altddio_out lp_tx_data_2 (
			  .datain_h	(ddr_data[2]),
			  .datain_l	(ddr_data[6]),
			  .outclock	(clk270),
			  .aclr		(~rst_n),
			  .dataout	(data_out[2])
			  );
  defparam 	
		lp_tx_data_2.width = 1,
		lp_tx_data_2.intended_device_family = DEVICE,
		lp_tx_data_2.oe_reg = "UNUSED",
		lp_tx_data_2.extend_oe_disable = "UNUSED",
		lp_tx_data_2.lpm_type = "altddio_out";

  altddio_out lp_tx_data_1 (
			  .datain_h	(ddr_data[1]),
			  .datain_l	(ddr_data[5]),
			  .outclock	(clk270),
			  .aclr		(~rst_n),
			  .dataout	(data_out[1])
			  );
  defparam 	
		lp_tx_data_1.width = 1,
		lp_tx_data_1.intended_device_family = DEVICE,
		lp_tx_data_1.oe_reg = "UNUSED",
		lp_tx_data_1.extend_oe_disable = "UNUSED",
		lp_tx_data_1.lpm_type = "altddio_out";

  altddio_out lp_tx_data_0 (
			  .datain_h	(ddr_data[0]),
			  .datain_l	(ddr_data[4]),
			  .outclock	(clk270),
			  .aclr		(~rst_n),
			  .dataout	(data_out[0])
			  );
  defparam 	
		lp_tx_data_0.width = 1,
		lp_tx_data_0.intended_device_family = DEVICE,
		lp_tx_data_0.oe_reg = "UNUSED",
		lp_tx_data_0.extend_oe_disable = "UNUSED",
		lp_tx_data_0.lpm_type = "altddio_out";

  always @(posedge clk4 or negedge rst_n)
    if (~rst_n)
      clk_en <= 1'b0;
    else if (tx_state[2])
      clk_en <= 1'b1;
    else if (tx_state[6] | tx_state[0] | tx_state[1])
      clk_en <= 1'b0;

  always @(posedge clk or negedge rst_n)
    if (~rst_n)
    begin
      clk_en_r <= 1'b0;
      clk_en_rr <= 1'b0;
      clk_en_rrr <= 1'b0;
    end
    else
    begin
      clk_en_r <= clk_en;
      clk_en_rr <= clk_en_r;
      clk_en_rrr <= clk_en | tvere & clk_en_rr;
    end

  wire 		clk_out;

  ddr_clk lp_tx_clk (
		     .datain_h	(clk_en_rrr),
		     .clk	(clk),
		     .dataout	(clk_out)
		     );

  reg [7:0] 	add2_1;
  reg [7:0] 	add2_2;
  reg [7:0] 	add3;
  always @(posedge clk4 or negedge rst_n)
    if (~rst_n)
    begin
      add2_1 <= 8'b0;
      add2_2 <= 8'b0;
    end
    else
    begin
      add2_1 <= tx_data[31:24] + tx_data[23:16];
      add2_2 <= tx_data[15:8] + tx_data[7:0];
    end
      
  always @(negedge clk4 or negedge rst_n)
    if (~rst_n)
      cksum_reg <= 8'b0;
    else if (~clk_en)
      cksum_reg <= 8'b0;
    else
      cksum_reg <= cksum_reg + add2_1 + add2_2;
      
/* -----\/----- EXCLUDED -----\/-----
  always @(posedge clk4 or negedge rst_n)
    if (~rst_n)
      cksum_reg <= 8'b0;
    else if (~clk_en)
      cksum_reg <= 8'b0;
    else
      cksum_reg <= cksum_reg + add3;
 -----/\----- EXCLUDED -----/\----- */

endmodule

⌨️ 快捷键说明

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