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

📄 generic_transmit_fifo.v

📁 一个关于以太网MAC核和介质无关接口的原代码,希望对大家有帮助!
💻 V
📖 第 1 页 / 共 5 页
字号:
   reg CODEWORD_RECENT;   wire COMPLETE_FRAME_TRANSMIT;   reg NEARLY_EMPTY_SIZE;   reg NEARLY_EMPTY_FRAME;   wire NEARLY_EMPTY_FRAME_TX;   reg NEARLY_EMPTY_SIZE_TX;   reg COMPLETE_FRAME_TRANSMIT_REG;   reg REALLY_EMPTY_TMP;   wire FRAME_TRANSMIT;   reg FRAME_TRANSMIT_REG;       assign DUMMY1 = 32'h00000000;    assign DUMMY2 = 4'b0000;    assign DUMMY3 = 16'h0000;    assign DUMMY4 = 2'b00;    assign DUMMY5 = 8'b00000000;    assign DUMMY6 = 1'b0;    assign DUMMY7 = 4'b0;    assign DUMMY8 = 2'b0;    assign DUMMY9 = 1'b0;    assign FRAME_COUNT_ZERO = 0;       assign WR_DATA = {LANE_VALID, DATA};               // LANE_VALID is attached to the top of DATA to provide the input to the FIFO    assign TX_DATA_VALID = DATA_VALID & VALID_EN;      // Enable DATA_VALID    assign WR_EN = WR_INC;                             // The write enable for the FIFO is also the increment pulse for the pointer    assign STATUS_UNDERRUN = INT_UNDERRUN_REG & CONTROL;    assign RD_EN_TEMP = RD_INC;                        // The read enable for the FIFO is also the increment pulse for the pointer    assign RD_EN = RD_EN_TEMP | TX_SRESET;             // The FIFO must be enabled for the sreset to work    assign CONTROL = RD_DATA[16];                      // Represents the value of LANE_VALID(0) at the read output    assign INT_NEARLY_FULL = PRE_FULL | FULL;          // Need to provide a > NEARLY_FULL signal    assign STATUS_FULL = FULL;                         // FULL is already in CLK domain, and so can go straight out    assign STATUS_NEARLY_FULL = NEARLY_FULL;           // NEARLY_FULL is already in CLK domain, and so can go straight out    assign STATUS_NEARLY_EMPTY = NEARLY_EMPTY;         // NEARLY_EMPTY is already in CLK domain    assign STATUS_EMPTY = STATUS_EMPTY_INT;            // STATUS_EMPTY_INT is also in CLK domain        always @(TX_UNDERRUN)    begin      TX_UNDERRUN_OUT <= #1000 TX_UNDERRUN;    end        always @(TX_DATA_INT)    begin      TX_DATA <= #1000 TX_DATA_INT;    end        always @(DATA_VALID_INT)    begin      DATA_VALID <= #1000 DATA_VALID_INT;    end    assign WR_POINTER_VECTOR = WR_POINTER;	assign RD_POINTER_VECTOR = RD_POINTER;        // Write increment logic    // FIFO can only write a data word (indicated by LANE_VALID(0) = 1'b1) when NEARLY_FULL = 1'b0,    // but can write a codeword at any time, all enabled by the bus WR_ENABLE    assign WRITE_ENABLE = (~(INT_NEARLY_FULL & LANE_VALID[0])) & WR_ENABLE & ((!CODEWORD_RECENT) || LANE_VALID[0]);    // Underrun logic    // An underrun signal will be generated if an acknowledge is received from the transmitter    // when the FIFO is EMPTY and the previous word sent was a data word (indicated by RD_DATA(128) = 1'b1),    // or when a forced UNDERRUN_PULSE is generated from the codeword    assign TX_UNDERRUN = ((INT_UNDERRUN_REG & CONTROL) | UNDERRUN_PULSE);    // Enable logic for DATA_VALID    // DATA_VALID is enabled when sending data words, but only when not in an UNDERRUN condition,    // where DATA_VALID must be kept at zero until the start of the next frame    assign VALID_EN = CONTROL & (~TX_UNDERRUN);    // Read increment logic    // FIFO can be read and incremented on a number of different occasions:    // 1. The device is just coming out of being EMPTY    // 2. The frame went UNDERRUN during transmission - the READ_ENABLE is then left high to cycle through    // to the end of the frame as quickly as possible, where the UNDERRUN status is cancelled.    // 3. A front loaded read_enable has been enabled        assign READ_ENABLE = PRE_READ_ENABLE | INT_UNDERRUN | ((~STATUS_EMPTY_INT_TX) & STATUS_EMPTY_INT_TX_REG & EMPTY_VALID & (~RD_DATA_INT[16]));    // The RD_DATA from the FIFO is registered to help with timing.  The data will only be registered    // to this registered when outputting a START signal or when HALF_BIT is high indicating that	// that the data needs to be read    assign OUT_ENABLE = START | HALF_BIT;    // Acknowledge logic    // An acknowledge is only sent to the bus when the data is being written into the FIFO    assign ACK = WR_EN;    // Error logic    // An error signal is sent when the bus tries to write data, but for some reason the    // internal logic will not let it be written into the FIFO    assign ERR = WR_ENABLE & (~WR_EN);        // purpose: Determine if any data has been received in frame    // type   : Sequential   always @(posedge CLK)   begin	  if (TX_FIFO_SRESET == 1'b1 || (WR_ENABLE == 1'b1 && LANE_VALID[0] == 1'b0))		 CODEWORD_RECENT <= 1'b1;	  else	  begin	     if (WR_ENABLE == 1'b1)			CODEWORD_RECENT <= 1'b0;	  end   end            // Create a pre_READ_ENABLE    // This creates a front loaded registered signal for the READ_ENABLE	// This should go high when:	// An acknowledge is received from the MAC or when in STREAM mode with DATA on the READ, and	// when in STREAM mode with no reading happening or an acknowledge is received, and top-half of data is selectecd,	// OR FIFO is not nearly empty when the read data is the first data after a control word,	// or the control word is the next one to read and the output is the top-half,	// and no start has just being sent or is being sent.		always @(TX_ACK or STREAM or CONTROL or RD_INC or HALF_BIT or NEARLY_EMPTY_TX or RD_DATA_INT[16] or START or START_REG)    begin      if (((TX_ACK == 1'b1 || (STREAM == 1'b1 && CONTROL == 1'b1)) &&            (((STREAM == 1'b1 && RD_INC == 1'b0) || TX_ACK == 1'b1) && HALF_BIT == 1'b0))             || (NEARLY_EMPTY_TX == 1'b0 && ((RD_DATA_INT[16] == 1'b1 && CONTROL == 1'b0)             || (RD_DATA_INT[16] == 1'b0 && CONTROL == 1'b1 && HALF_BIT == 1'b1 ))             && START == 1'b0 && START_REG == 1'b0))        PRE_READ_ENABLE_COMB <= 1'b1;      else        PRE_READ_ENABLE_COMB <= 1'b0;    end         always @(posedge TX_CLK)    begin      if (TX_SRESET == 1'b1)        PRE_READ_ENABLE <= 1'b0;      else        PRE_READ_ENABLE <= PRE_READ_ENABLE_COMB;    end         // Generate the correct size and number of block rams for the FIFO_SIZE passed in        assign WR_DATA_PADDED = {16'h0000, WR_DATA[15:0]};    assign WR_VLD_PADDED = {2'b00, WR_DATA[17:16]};        // Instantiate the correct size and number of block rams...    // We need to use Verilog2001 features to do this. These are currently supported by XST,    // and MTI support is slated for December...    integer i;    integer j;    // Use the code below when Verilog 2001 generate statements are supported....    /*        generate      if (FIFO_SIZE >= 512)       begin        generate          for (i = 0; i < 1; i = i + 1)          begin        	RAMB16_S36_S36 RAM_SIZE111               (.DIA(WR_DATA_PADDED),                .DIB(DUMMY1),                .DIPA(WR_VLD_PADDED),                .DIPB(DUMMY2),                .ENA(PWR),                .ENB(RD_EN),                .WEA(WR_EN),                .WEB(GND),                .SSRA(GND),                .SSRB(TX_SRESET),                .CLKA(CLK),                .CLKB(TX_CLK),                .ADDRA(WR_POINTER_VECTOR),                .ADDRB(RD_POINTER_VECTOR),                .DOB(RD_TEMP1),                .DOPB(RD_TEMP2)                );          end        endgenerate                assign RD_DATA_INT = {RD_TEMP2[1:0], RD_TEMP1[15:0]};      end            else if(FIFO_SIZE == 1024)      begin        generate          for (i = 0; i < 1; i = i + 1)          begin        	RAMB16_S18_S18 RAM_SIZE211               (.DIA(WR_DATA[15:0]),                .DIB(DUMMY3),                .DIPA(WR_DATA[17:16]),                .DIPB(DUMMY4),                .ENA(PWR),                .ENB(RD_EN),                .WEA(WR_EN),                .WEB(GND),                .SSRA(GND),                .SSRB(TX_SRESET),                .CLKA(CLK),                .CLKB(TX_CLK),                .ADDRA(WR_POINTER_VECTOR),                .ADDRB(RD_POINTER_VECTOR),                .DOB(RD_DATA_INT[15:0]),                .DOPB(RD_DATA_INT[17:16])                );          end        endgenerate      end      else if(FIFO_SIZE == 2048)      begin        generate          for (i = 0; i < 2; i = i + 1)          begin        	RAMB16_S9_S9 RAM_SIZE311               (.DIA(WR_DATA[(i*8)+7:(i*8)]),                .DIB(DUMMY5),                .DIPA(WR_DATA[i+16:i+16]),                .DIPB(DUMMY6),                .ENA(PWR),                .ENB(RD_EN),                .WEA(WR_EN),                .WEB(GND),                .SSRA(GND),                .SSRB(TX_SRESET),                .CLKA(CLK),                .CLKB(TX_CLK),                .ADDRA(WR_POINTER_VECTOR),                .ADDRB(RD_POINTER_VECTOR),                .DOB(RD_DATA_INT[(i*8)+7:(i*8)]),                .DOPB(RD_DATA_INT[i+16:i+16])                );          end        endgenerate      end      else if(FIFO_SIZE == 4096)      begin        generate          for (i = 0; i < 4; i = i + 1)          begin        	RAMB16_S4_S4 RAM_SIZE411               (.DIA(WR_DATA[(i*4)+3:(i*4)]),                .DIB(DUMMY7),                .ENA(PWR),                .ENB(RD_EN),                .WEA(WR_EN),                .WEB(GND),                .SSRA(GND),                .SSRB(TX_SRESET),                .CLKA(CLK),                .CLKB(TX_CLK),                .ADDRA(WR_POINTER_VECTOR),                .ADDRB(RD_POINTER_VECTOR),                .DOB(RD_DATA_INT[(i*4)+3:(i*4)])                );          end        endgenerate        assign WR_DATA_PAD2 = {2'b00, WR_DATA[17:16]};        RAMB16_S4_S4 RAM_SIZE41B           (.DIA(WR_DATA_PAD2),            .DIB(DUMMY7),            .ENA(PWR),            .ENB(RD_EN),            .WEA(WR_EN),            .WEB(GND),            .SSRA(GND),            .SSRB(TX_SRESET),            .CLKA(CLK),            .CLKB(TX_CLK),            .ADDRA(WR_POINTER_VECTOR),            .ADDRB(RD_POINTER_VECTOR),            .DOB(RD_TEMP3)            );        assign RD_DATA_INT[17:16] = RD_TEMP3[1:0];      end      else if(FIFO_SIZE == 8192)      begin        generate          for (i = 0; i < 9; i = i + 1)          begin        	RAMB16_S2_S2 RAM_SIZE511               (.DIA(WR_DATA[(i*2)+1:(i*2)]),                .DIB(DUMMY4),                .ENA(PWR),                .ENB(RD_EN),                .WEA(WR_EN),                .WEB(GND),                .SSRA(GND),                .SSRB(TX_SRESET),                .CLKA(CLK),                .CLKB(TX_CLK),                .ADDRA(WR_POINTER_VECTOR),                .ADDRB(RD_POINTER_VECTOR),                .DOB(RD_DATA_INT[(i*2)+1:(i*2)])                );          end        endgenerate      end      else // (FIFO_SIZE == 16384)      begin        generate          for (i = 0; i < 18; i = i + 1)          begin        	RAMB16_S1_S1 RAM_SIZE611               (.DIA(WR_DATA[i:i]),                .DIB(DUMMY9),                .ENA(PWR),                .ENB(RD_EN),                .WEA(WR_EN),                .WEB(GND),                .SSRA(GND),                .SSRB(TX_SRESET),                .CLKA(CLK),                .CLKB(TX_CLK),                .ADDRA(WR_POINTER_VECTOR),                .ADDRB(RD_POINTER_VECTOR),                .DOB(RD_DATA_INT[i:i])                );          end        endgenerate      end              endgenerate    */        // CHANGES REQUIRED    // Use the code below when Verilog 2001 generate statements are NOT supported...    // Uncomment the code for the correct FIFO_SIZE...    // (FIFO_SIZE == 512)      /*    RAMB16_S36_S36 RAM_SIZE111               (.DIA(WR_DATA_PADDED),                .DIB(DUMMY1),                .DIPA(WR_VLD_PADDED),                .DIPB(DUMMY2),                .ENA(PWR),                .ENB(RD_EN),                .WEA(WR_EN),                .WEB(GND),                .SSRA(GND),                .SSRB(TX_SRESET),                .CLKA(CLK),                .CLKB(TX_CLK),                .ADDRA(WR_POINTER_VECTOR),                .ADDRB(RD_POINTER_VECTOR),                .DOB(RD_TEMP1),                .DOPB(RD_TEMP2)                );            assign RD_DATA_INT = {RD_TEMP2[1:0], RD_TEMP1[15:0]};

⌨️ 快捷键说明

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