📄 eth_wishbone.v
字号:
ram_di <=#Tp 32'h0; BDRead <=#Tp 1'b0; BDWrite <=#Tp 1'b0; end else begin // Switching between three stages depends on enable signals case ({WbEn_q, RxEn_q, TxEn_q, RxEn_needed, TxEn_needed}) // synopsys parallel_case 5'b100_10, 5'b100_11 : begin WbEn <=#Tp 1'b0; RxEn <=#Tp 1'b1; // wb access stage and r_RxEn is enabled TxEn <=#Tp 1'b0; ram_addr <=#Tp RxBDAddress + RxPointerRead; ram_di <=#Tp RxBDDataIn; end 5'b100_01 : begin WbEn <=#Tp 1'b0; RxEn <=#Tp 1'b0; TxEn <=#Tp 1'b1; // wb access stage, r_RxEn is disabled but r_TxEn is enabled ram_addr <=#Tp TxBDAddress + TxPointerRead; ram_di <=#Tp TxBDDataIn; end 5'b010_00, 5'b010_10 : begin WbEn <=#Tp 1'b1; // RxEn access stage and r_TxEn is disabled RxEn <=#Tp 1'b0; TxEn <=#Tp 1'b0; ram_addr <=#Tp WB_ADR_I[9:2]; ram_di <=#Tp WB_DAT_I; BDWrite <=#Tp BDCs & WB_WE_I; BDRead <=#Tp BDCs & ~WB_WE_I; end 5'b010_01, 5'b010_11 : begin WbEn <=#Tp 1'b0; RxEn <=#Tp 1'b0; TxEn <=#Tp 1'b1; // RxEn access stage and r_TxEn is enabled ram_addr <=#Tp TxBDAddress + TxPointerRead; ram_di <=#Tp TxBDDataIn; end 5'b001_00, 5'b001_01, 5'b001_10, 5'b001_11 : begin WbEn <=#Tp 1'b1; // TxEn access stage (we always go to wb access stage) RxEn <=#Tp 1'b0; TxEn <=#Tp 1'b0; ram_addr <=#Tp WB_ADR_I[9:2]; ram_di <=#Tp WB_DAT_I; BDWrite <=#Tp BDCs & WB_WE_I; BDRead <=#Tp BDCs & ~WB_WE_I; end 5'b100_00 : begin WbEn <=#Tp 1'b0; // WbEn access stage and there is no need for other stages. WbEn needs to be switched off for a bit end 5'b000_00 : begin WbEn <=#Tp 1'b1; // Idle state. We go to WbEn access stage. RxEn <=#Tp 1'b0; TxEn <=#Tp 1'b0; ram_addr <=#Tp WB_ADR_I[9:2]; ram_di <=#Tp WB_DAT_I; BDWrite <=#Tp BDCs & WB_WE_I; BDRead <=#Tp BDCs & ~WB_WE_I; end endcase endend// Delayed stage signalsalways @ (posedge WB_CLK_I or posedge Reset)begin if(Reset) begin WbEn_q <=#Tp 1'b0; RxEn_q <=#Tp 1'b0; TxEn_q <=#Tp 1'b0; end else begin WbEn_q <=#Tp WbEn; RxEn_q <=#Tp RxEn; TxEn_q <=#Tp TxEn; endend// Changes for tx occur every second clock. Flop is used for this manner.always @ (posedge MTxClk or posedge Reset)begin if(Reset) Flop <=#Tp 1'b0; else if(TxDone | TxAbort | TxRetry_q) Flop <=#Tp 1'b0; else if(TxUsedData) Flop <=#Tp ~Flop;endwire ResetTxBDReady;assign ResetTxBDReady = TxDonePulse | TxAbortPulse | TxRetryPulse;// Latching READY status of the Tx buffer descriptoralways @ (posedge WB_CLK_I or posedge Reset)begin if(Reset) TxBDReady <=#Tp 1'b0; else if(TxEn & TxEn_q & TxBDRead) TxBDReady <=#Tp ram_do[15] & (ram_do[31:16] > 4); // TxBDReady is sampled only once at the beginning. else // Only packets larger then 4 bytes are transmitted. if(ResetTxBDReady) TxBDReady <=#Tp 1'b0;end// Reading the Tx buffer descriptorassign StartTxBDRead = (TxRetry_wb | TxStatusWrite) & ~BlockingTxBDRead & ~TxBDReady;always @ (posedge WB_CLK_I or posedge Reset)begin if(Reset) TxBDRead <=#Tp 1'b1; else if(StartTxBDRead) TxBDRead <=#Tp 1'b1; else if(TxBDReady) TxBDRead <=#Tp 1'b0;end// Reading Tx BD pointerassign StartTxPointerRead = TxBDRead & TxBDReady;// Reading Tx BD Pointeralways @ (posedge WB_CLK_I or posedge Reset)begin if(Reset) TxPointerRead <=#Tp 1'b0; else if(StartTxPointerRead) TxPointerRead <=#Tp 1'b1; else if(TxEn_q) TxPointerRead <=#Tp 1'b0;end// Writing status back to the Tx buffer descriptorassign TxStatusWrite = (TxDone_wb | TxAbort_wb) & TxEn & TxEn_q & ~BlockingTxStatusWrite;// Status writing must occur only once. Meanwhile it is blocked.always @ (posedge WB_CLK_I or posedge Reset)begin if(Reset) BlockingTxStatusWrite <=#Tp 1'b0; else if(TxStatusWrite) BlockingTxStatusWrite <=#Tp 1'b1; else if(~TxDone_wb & ~TxAbort_wb) BlockingTxStatusWrite <=#Tp 1'b0;end// TxBDRead state is activated only once. always @ (posedge WB_CLK_I or posedge Reset)begin if(Reset) BlockingTxBDRead <=#Tp 1'b0; else if(StartTxBDRead) BlockingTxBDRead <=#Tp 1'b1; else if(~StartTxBDRead & ~TxBDReady) BlockingTxBDRead <=#Tp 1'b0;end// Latching status from the tx buffer descriptor// Data is avaliable one cycle after the access is started (at that time signal TxEn is not active)always @ (posedge WB_CLK_I or posedge Reset)begin if(Reset) TxStatus <=#Tp 4'h0; else if(TxEn & TxEn_q & TxBDRead) TxStatus <=#Tp ram_do[14:11];endreg ReadTxDataFromMemory;wire WriteRxDataToMemory;reg MasterWbTX;reg MasterWbRX;reg [31:0] m_wb_adr_o;reg m_wb_cyc_o;reg m_wb_stb_o;reg [3:0] m_wb_sel_o;reg m_wb_we_o;wire TxLengthEq0;wire TxLengthLt4;reg BlockingIncrementTxPointer;reg [31:0] TxPointer;reg [1:0] TxPointerLatched;reg [1:0] TxPointerLatched_rst;reg [31:0] RxPointer;reg [1:0] RxPointerLatched;wire RxBurstAcc;wire RxWordAcc;wire RxHalfAcc;wire RxByteAcc;//Latching length from the buffer descriptor;always @ (posedge WB_CLK_I or posedge Reset)begin if(Reset) TxLength <=#Tp 16'h0; else if(TxEn & TxEn_q & TxBDRead) TxLength <=#Tp ram_do[31:16]; else if(MasterWbTX & m_wb_ack_i) begin if(TxLengthLt4) TxLength <=#Tp 16'h0; else if(TxPointerLatched_rst==2'h0) TxLength <=#Tp TxLength - 3'h4; // Length is subtracted at the data request else if(TxPointerLatched_rst==2'h1) TxLength <=#Tp TxLength - 3'h3; // Length is subtracted at the data request else if(TxPointerLatched_rst==2'h2) TxLength <=#Tp TxLength - 3'h2; // Length is subtracted at the data request else if(TxPointerLatched_rst==2'h3) TxLength <=#Tp TxLength - 3'h1; // Length is subtracted at the data request endend//Latching length from the buffer descriptor;always @ (posedge WB_CLK_I or posedge Reset)begin if(Reset) LatchedTxLength <=#Tp 16'h0; else if(TxEn & TxEn_q & TxBDRead) LatchedTxLength <=#Tp ram_do[31:16];endassign TxLengthEq0 = TxLength == 0;assign TxLengthLt4 = TxLength < 4;reg cyc_cleared;reg IncrTxPointer;//Latching Tx buffer pointer from buffer descriptor;always @ (posedge WB_CLK_I or posedge Reset)begin if(Reset) TxPointer <=#Tp 0; else if(TxEn & TxEn_q & TxPointerRead) TxPointer <=#Tp ram_do; else if(IncrTxPointer & ~BlockingIncrementTxPointer) TxPointer <=#Tp TxPointer + 3'h4; // Word accessend//Latching last addresses from buffer descriptor (used as byte-half-word indicator);always @ (posedge WB_CLK_I or posedge Reset)begin if(Reset) TxPointerLatched[1:0] <=#Tp 0; else if(TxEn & TxEn_q & TxPointerRead) TxPointerLatched[1:0] <=#Tp ram_do[1:0];end//Latching last addresses from buffer descriptor (used as byte-half-word indicator);always @ (posedge WB_CLK_I or posedge Reset)begin if(Reset) TxPointerLatched_rst[1:0] <=#Tp 0; else if(TxEn & TxEn_q & TxPointerRead) TxPointerLatched_rst[1:0] <=#Tp ram_do[1:0]; else if(MasterWbTX & m_wb_ack_i) // After first access pointer is word alligned TxPointerLatched_rst[1:0] <=#Tp 0;endreg [3:0] m_wb_sel_tmp_rx;wire MasterAccessFinished;always @ (posedge WB_CLK_I or posedge Reset)begin if(Reset) BlockingIncrementTxPointer <=#Tp 0; else if(MasterAccessFinished) BlockingIncrementTxPointer <=#Tp 0; else if(IncrTxPointer) BlockingIncrementTxPointer <=#Tp 1'b1;endwire TxBufferAlmostFull;wire TxBufferFull;wire TxBufferEmpty;wire TxBufferAlmostEmpty;wire ResetReadTxDataFromMemory;wire SetReadTxDataFromMemory;reg BlockReadTxDataFromMemory;assign ResetReadTxDataFromMemory = (TxLengthEq0) | TxAbortPulse_q | TxRetryPulse_q;assign SetReadTxDataFromMemory = TxEn & TxEn_q & TxPointerRead;always @ (posedge WB_CLK_I or posedge Reset)begin if(Reset) ReadTxDataFromMemory <=#Tp 1'b0; else if(ResetReadTxDataFromMemory) ReadTxDataFromMemory <=#Tp 1'b0; else if(SetReadTxDataFromMemory) ReadTxDataFromMemory <=#Tp 1'b1;endwire ReadTxDataFromMemory_2 = ReadTxDataFromMemory & ~BlockReadTxDataFromMemory;wire [31:0] TxData_wb;wire ReadTxDataFromFifo_wb;always @ (posedge WB_CLK_I or posedge Reset)begin if(Reset) BlockReadTxDataFromMemory <=#Tp 1'b0; else if(ReadTxDataFromFifo_wb | ResetReadTxDataFromMemory) BlockReadTxDataFromMemory <=#Tp 1'b0; else if((TxBufferAlmostFull | TxLength <= 4)& MasterWbTX) BlockReadTxDataFromMemory <=#Tp 1'b1;endassign MasterAccessFinished = m_wb_ack_i | m_wb_err_i;reg [3:0] state;// Enabling master wishbone access to the memory for two devices TX and RX.always @ (posedge WB_CLK_I or posedge Reset)begin if(Reset) begin state <=#Tp 4'h0; MasterWbTX <=#Tp 1'b0; MasterWbRX <=#Tp 1'b0; m_wb_adr_o <=#Tp 32'h0; m_wb_cyc_o <=#Tp 1'b0; m_wb_stb_o <=#Tp 1'b0; m_wb_we_o <=#Tp 1'b0; m_wb_sel_o <=#Tp 4'h0; cyc_cleared<=#Tp 1'b0; IncrTxPointer<=#Tp 1'b0; end else begin // Switching between two stages depends on enable signals casex ({MasterWbTX, MasterWbRX, ReadTxDataFromMemory_2, WriteRxDataToMemory, MasterAccessFinished, cyc_cleared}) // synopsys parallel_case 6'b00_01_0_x, 6'b00_11_0_x : begin state <=#Tp 4'h1; MasterWbTX <=#Tp 1'b0; // idle and master write is needed (data write to rx buffer) MasterWbRX <=#Tp 1'b1; m_wb_adr_o <=#Tp RxPointer; m_wb_cyc_o <=#Tp 1'b1; m_wb_stb_o <=#Tp 1'b1; m_wb_we_o <=#Tp 1'b1; m_wb_sel_o <=#Tp m_wb_sel_tmp_rx; IncrTxPointer<=#Tp 1'b0; end 6'b00_10_0_x, 6'b00_10_1_x : begin state <=#Tp 4'h2; MasterWbTX <=#Tp 1'b1; // idle and master read is needed (data read from tx buffer) MasterWbRX <=#Tp 1'b0; m_wb_adr_o <=#Tp {TxPointer[31:2], 2'h0}; m_wb_cyc_o <=#Tp 1'b1; m_wb_stb_o <=#Tp 1'b1; m_wb_we_o <=#Tp 1'b0; m_wb_sel_o <=#Tp 4'hf; IncrTxPointer<=#Tp 1'b1; end 6'b10_10_0_1 : begin state <=#Tp 4'h3; MasterWbTX <=#Tp 1'b1; // master read and master read is needed (data read from tx buffer) MasterWbRX <=#Tp 1'b0; m_wb_adr_o <=#Tp {TxPointer[31:2], 2'h0}; m_wb_cyc_o <=#Tp 1'b1; m_wb_stb_o <=#Tp 1'b1; m_wb_we_o <=#Tp 1'b0; m_wb_sel_o <=#Tp 4'hf; cyc_cleared<=#Tp 1'b0; IncrTxPointer<=#Tp 1'b1; end 6'b01_01_0_1 : begin state <=#Tp 4'h4; MasterWbTX <=#Tp 1'b0; // master write and master write is needed (data write to rx buffer) MasterWbRX <=#Tp 1'b1; m_wb_adr_o <=#Tp RxPointer; m_wb_cyc_o <=#Tp 1'b1; m_wb_stb_o <=#Tp 1'b1; m_wb_we_o <=#Tp 1'b1; m_wb_sel_o <=#Tp m_wb_sel_tmp_rx; cyc_cleared<=#Tp 1'b0; IncrTxPointer<=#Tp 1'b0; end 6'b10_01_0_1, 6'b10_11_0_1 : begin state <=#Tp 4'h5; MasterWbTX <=#Tp 1'b0; // master read and master write is needed (data write to rx buffer) MasterWbRX <=#Tp 1'b1; m_wb_adr_o <=#Tp RxPointer; m_wb_cyc_o <=#Tp 1'b1; m_wb_stb_o <=#Tp 1'b1; m_wb_we_o <=#Tp 1'b1; m_wb_sel_o <=#Tp m_wb_sel_tmp_rx; cyc_cleared<=#Tp 1'b0; IncrTxPointer<=#Tp 1'b0; end 6'b01_10_0_1, 6'b01_11_0_1 : begin state <=#Tp 4'h6; MasterWbTX <=#Tp 1'b1; // master write and master read is needed (data read from tx buffer) MasterWbRX <=#Tp 1'b0; m_wb_adr_o <=#Tp {TxPointer[31:2], 2'h0}; m_wb_cyc_o <=#Tp 1'b1; m_wb_stb_o <=#Tp 1'b1; m_wb_we_o <=#Tp 1'b0; m_wb_sel_o <=#Tp 4'hf; cyc_cleared<=#Tp 1'b0; IncrTxPointer<=#Tp 1'b1; end 6'b10_10_1_0, 6'b01_01_1_0, 6'b10_01_1_0, 6'b10_11_1_0, 6'b01_10_1_0, 6'b01_11_1_0 : begin state <=#Tp 4'h7; m_wb_cyc_o <=#Tp 1'b0; // whatever and master read or write is needed. We need to clear m_wb_cyc_o before next access is started m_wb_stb_o <=#Tp 1'b0; cyc_cleared<=#Tp 1'b1; IncrTxPointer<=#Tp 1'b0; end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -