📄 fifoctrl.v
字号:
//////////////////////////////////////////////////////////////////////////////////////////////////----------------------------------------------------------------------//// Copyright (c) 2002-2003 CAST, inc.//// Please review the terms of the license agreement before using this// file. If you are not an authorized user, please destroy this source// code file and notify CAST immediately that you inadvertently received// an unauthorized copy.//----------------------------------------------------------------------//// Project : H16550 UART//// File : fifoctrl.v//// Dependencies : uart_fifo.v //// Model Type : Synthesizable Core//// Description : Fifo controller//// Designer : JU//// QA Engineer : JH//// Creation Date : 02-January-2002//// Last Update : 20-June-2003//// Version : 2.0V//// History : 1.1 - 02/18/02 VHDL Release// 1.2 - 04/16/02 Reduce Receiver's RAMs// Reduce Receiver and Transmitter read/write // address to 4 bits// Performance (size) improved// Transmit Fifo reset will reset read/write pointer to 0// Receiver Fifo reset will reset read/write pointer to 0// 1.4 - 02/21/03 lsreg00 that reset the rxrdy problem fixed (line 312)// 2.0 - 06/20/03 Add prevrdlsr to be mapped to uart_reg// Renamed fifo component to uart_fifo// Add FIFOREG generic to uart_fifo component// Delaying prevrd_rbr so that it works for Synchronous RAM// Rename RXRDY and TXRDY to RXRDYN and TXRDYN// Add txfifo_2char for THRE indication delay time// Fix txrdyn_fifo for Mode1////----------------------------------------------------------------------`timescale 1 ns/1 psmodule fifoctrl (rclk, clk, rd, wr, rbrint, mr, write_rxfifo, read_txfifo, write_thr, read_lsr, d, fcreg, rxf, lsreg, prevrdlsr, at_trig_level, rbrint1, fcreg11, fcreg21, lsreg_b2, lsreg_b3, lsreg_b4, lsreg_b0, lsreg51, lsreg_b7, txfifo_empty, txfifo_2char, rxfifo_full, rxfifo_empty, rxrdyn, txrdyn, rbreg, threg); `include "h16550_params.v" input rclk; // Receiver Clock input clk; // System clock input rd; // Read Enable input wr; // Write Enable input rbrint; // RBR interrupt input mr; // Master reset input write_rxfifo; // Write Receiver fifo enable input read_txfifo; // Read Transmitter fifo enable input write_thr; // Write Transmitter Hold Register enable input read_lsr; // Read Line Status Register enable input[DATA_WIDTH - 1:0] d; // data bus input input[5:0] fcreg; // Fifo Control register input[10:0] rxf; // Receiver Fifo Data input[DATA_WIDTH - 1:0] lsreg; // Line Status Register output prevrdlsr; // previous lsr read controller wire prevrdlsr; output at_trig_level; // Flag for trigger level reg at_trig_level; output rbrint1; // RBR interrupt enable 1 wire rbrint1; output fcreg11; // Fifo Control register bit 1 enable wire fcreg11; output fcreg21; // Fifo Control register bit 2 enable wire fcreg21; output lsreg_b2; // Line Status register bit 2 reg lsreg_b2; output lsreg_b3; // Line Status register bit 3 reg lsreg_b3; output lsreg_b4; // Line Status register bit 4 reg lsreg_b4; output lsreg_b0; // Line Status register bit 0 wire lsreg_b0; output lsreg51; // Line Status register bit 5 enable wire lsreg51; output lsreg_b7; // Line Status register bit 7 reg lsreg_b7; output txfifo_empty; // Transmitter Fifo Empty Flag wire txfifo_empty; output txfifo_2char; // Transmitter Fifo has 2 characters reg txfifo_2char; output rxfifo_full; // Receiver Fifo Full Flag wire rxfifo_full; output rxfifo_empty; // Receiver Fifo Empty Flag wire rxfifo_empty; output rxrdyn; // Receiver Ready reg rxrdyn; output txrdyn; // Transmitter Ready reg txrdyn; output[DATA_WIDTH - 1:0] rbreg; // Receiver Buffer register wire[DATA_WIDTH - 1:0] rbreg; output[DATA_WIDTH - 1:0] threg; wire[DATA_WIDTH - 1:0] threg; reg[3:0] rxwr_addr; reg[3:0] rxrd_addr; reg[3:0] txwr_addr; reg[3:0] txrd_addr; reg[3:0] fifo_err_add; reg[4:0] txfifo_value; reg[4:0] rxfifo_value; reg[3:0] trig; wire[1:0] fcreg54; wire[2:0] rbreg_rxf; reg txfifo_full; wire txrdyn_fifo; wire rxrdyn_fifo; reg txrdy1; reg txrdy2; reg rxrdy1; reg rxrdy2; reg rxrdy3; wire rxfifo_wr; reg rbrint1_int; reg fcreg11_int; reg fcreg21_int; reg lsreg51_int; reg txfifo_empty_int; reg rxfifo_full_int; reg rxfifo_empty_int; wire fcreg0; wire lsreg5; wire lsreg0; wire lsreg1; reg lsreg00; reg lsreg01; wire reset_rxfifo; wire reset_txfifo; reg prevrd_lsr; reg prevrd_rbr; reg prevrd_rbr_dly; reg txfifo_halffull; reg rxfifo_halffull; assign rbrint1 = rbrint1_int ; assign fcreg11 = fcreg11_int ; assign fcreg21 = fcreg21_int ; assign lsreg51 = lsreg51_int ; assign lsreg_b0 = lsreg00 ^ lsreg01 ; assign txfifo_empty = txfifo_empty_int ; assign rxfifo_full = rxfifo_full_int ; assign rxfifo_empty = rxfifo_empty_int ; assign prevrdlsr = prevrd_lsr ; assign txrdyn_fifo = txrdy1 ^ txrdy2 ; assign rxrdyn_fifo = rxrdy1 ^ rxrdy2 ^ rxrdy3 ; assign fcreg0 = fcreg[0] ; assign lsreg5 = lsreg[5] ; assign lsreg0 = lsreg[0] ; assign lsreg1 = lsreg[1] ; assign rxfifo_wr = (write_rxfifo == 1'b1 & (rxfifo_full_int == 1'b0 | fcreg0 == 1'b0)) ? 1'b1 : 1'b0 ; //------------------- // Select TXRDY mode //------------------- always @(posedge mr or negedge clk) begin if (mr == 1'b1) begin txrdyn <= 1'b0 ; end else begin if ((fcreg[3]) == 1'b0) begin // norm mode txrdyn <= ~lsreg5 ; // THRE end else begin txrdyn <= txrdyn_fifo ; // mode 1 end end end //------------------------ // Select RXRDY mode //------------------------ always @(posedge mr or negedge clk) begin if (mr == 1'b1) begin rxrdyn <= 1'b1 ; end else begin if ((fcreg[3]) == 1'b0) begin // norm mode rxrdyn <= ~lsreg0 ; // DR end else begin rxrdyn <= rxrdyn_fifo ; end end end //-------------------------------------- // FIFO control register bit 1 reset //-------------------------------------- always @(posedge mr or posedge rclk) begin if (mr == 1'b1) begin fcreg11_int <= 1'b0 ; end else begin if ((fcreg[1]) == 1'b1) begin fcreg11_int <= ~fcreg11_int ; end end end //----------------------------------- // FIFO control register bit 2 reset //----------------------------------- always @(posedge mr or posedge clk) begin if (mr == 1'b1) begin fcreg21_int <= 1'b0 ; end else begin if ((fcreg[2]) == 1'b1) begin fcreg21_int <= ~fcreg21_int ; end end end //----------------------- // Trigger level checking //----------------------- assign fcreg54 = {fcreg[5], fcreg[4]} ; always @(fcreg54) begin case (fcreg54) 2'b00 : begin trig <= 4'b0001 ; end 2'b01 : begin trig <= 4'b0100 ; end 2'b10 : begin trig <= 4'b1000 ; end default : begin trig <= 4'b1110 ; end endcase end always @(trig or rxfifo_value) begin if (rxfifo_value <= trig) begin at_trig_level <= 1'b1 ; end else begin at_trig_level <= 1'b0 ; end end always @(posedge mr or posedge rclk) begin if (mr == 1'b1) begin rbrint1_int <= 1'b0 ; end else begin if (((fcreg[1]) == 1'b0 & write_rxfifo == 1'b1 & rbrint == 1'b0) & ((fcreg0 == 1'b1 & rxfifo_full_int == 1'b0 & (rxfifo_value + 1 >= trig)) | (fcreg0 == 1'b0))) begin rbrint1_int <= ~rbrint1_int ; // Rec Data Avail interrupt end end end always @(posedge mr or negedge rd) begin if (mr == 1'b1) begin rxrdy1 <= 1'b1 ; end else begin if ((fcreg0 == 1'b1 & (fcreg[1]) == 1'b0) & (write_thr == 1'b1 & rxfifo_empty_int == 1'b0) & (rxrdyn_fifo == 1'b0 & rxfifo_value == 5'b00001)) begin // mode 1 rxrdy1 <= ~rxrdy1 ; end end end always @(posedge mr or posedge rclk) begin if (mr == 1'b1) begin rxrdy2 <= 1'b0 ; rxrdy3 <= 1'b0 ; end else begin if (fcreg0 == 1'b1 & (fcreg[1]) == 1'b0 & write_rxfifo == 1'b1 & rxfifo_full_int == 1'b0 & (rxfifo_value + 1 >= trig) & rxrdyn_fifo == 1'b1) begin rxrdy2 <= ~rxrdy2 ; end // In Mode1, Reseting RCVR Fifo will set RXRDY if (fcreg0 == 1'b1 & (fcreg[1]) == 1'b1 & rxrdyn_fifo == 1'b0) begin rxrdy3 <= ~rxrdy3 ; end end end always @(posedge mr or posedge clk) begin if (mr == 1'b1) begin prevrd_lsr <= 1'b0 ; prevrd_rbr <= 1'b0 ; prevrd_rbr_dly <= 1'b0 ; end else begin prevrd_lsr <= rd & read_lsr ; prevrd_rbr <= rd & write_thr ; prevrd_rbr_dly <= prevrd_rbr ; end end //---------------------------------- // LINE STATUS register bit 0 reset //---------------------------------- always @(posedge mr or negedge rd) begin if (mr == 1'b1) begin lsreg00 <= 1'b0 ; end else begin if (write_thr == 1'b1 & (rxfifo_value == 5'b00001 | fcreg0 == 1'b0) & lsreg0 == 1'b1) begin lsreg00 <= ~(lsreg00) ; end end end always @(posedge mr or posedge rclk) begin if (mr == 1'b1) begin lsreg01 <= 1'b0 ; end else begin if ((((fcreg[1]) == 1'b0 & write_rxfifo == 1'b1 & lsreg0 == 1'b0) & ((fcreg0 == 1'b1 & rxfifo_full_int == 1'b0) | (fcreg0 == 1'b0))) | (lsreg0 == 1'b1 & (fcreg[1]) == 1'b1)) begin lsreg01 <= ~lsreg01 ; // set/reset DR end end end //--------------------------------------- // the received data character have PE // In the fifo mode this PE is associated with the particular // character in the fifo it applies to. This error is revealed to the // CPU when its associated character is at the top of the fifo //--------------------------------------- always @(posedge mr or posedge clk) begin if (mr == 1'b1) begin lsreg_b2 <= 1'b0 ; end else begin if (((fcreg[1]) == 1'b0 & write_rxfifo == 1'b1 & (lsreg[2]) == 1'b0 & (rxf[0]) == 1'b1) & ((fcreg0 == 1'b1 & rxfifo_full_int == 1'b0 & rxfifo_empty_int == 1'b1) | (fcreg0 == 1'b0))) begin lsreg_b2 <= 1'b1 ; // set PE end if ((fcreg0 == 1'b1 & prevrd_rbr_dly == 1'b1 & rd == 1'b0) & (rxfifo_empty_int == 1'b0) & ((lsreg[2]) == 1'b0 & (rbreg_rxf[0]) == 1'b1)) begin lsreg_b2 <= 1'b1 ; // set PE end if (prevrd_lsr == 1'b1 & rd == 1'b0 & (lsreg[2]) == 1'b1) begin lsreg_b2 <= 1'b0 ; // reset PE end end end //--------------------------------------- // the received data character have FE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -