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

📄 uart_reg.v

📁 专门做处理器和周边接口的著名ipcore厂商CAST出品的UART H16550
💻 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          : uart_reg.v////  Dependencies  : none ////  Model Type    : Synthesizable Core////  Description   : h16550 uart_reg////  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    Performance (size) improved//                  2.0 - 06/20/03    Use prevrdlsr to control the lsreg10//                                    renamed registers to uart_reg//                                    Add thrint5////----------------------------------------------------------------------`timescale 1 ns/1 psmodule uart_reg (clk, wr, mr, rd, write_thr, write_dlr, write_dmr, ena_ier, ena_lcr, ena_mcr, ena_sr, read_msr, read_iir, prevrdlsr, ctsn, dsrn, dcdn, rin, sin, lsreg_b0, lsreg11, lsreg_b2, lsreg_b3, lsreg_b4, lsreg51, lsreg_b7, temt, fcreg11, fcreg21, thrint, sout_org, d, thrint4, thrint5, sin_org, rtsn, dtrn, out1n, out2n, sout, dmreg, dlreg, iereg, lcreg, lsreg, mcreg, msreg, fcreg, sreg);   `include "h16550_params.v"   input clk; // System Clock   input wr; // Write Enable   input mr; // Master Reset   input rd; // Read Enable   input write_thr; // Write Transmitter holding register enable   input write_dlr; // Write LSB divisor register enable   input write_dmr; // Write MSB divisor register enable   input ena_ier; // Interrupt Enable register enable   input ena_lcr; // Line control register enable   input ena_mcr; // Modem control register enable   input ena_sr; // Scratch pad register enable   input read_msr; // Read Modem status register enable   input read_iir; // Read interrupt status register enable   input prevrdlsr; // previous lsr read controller   input ctsn; // Clear To Send Enable   input dsrn; // Data Set Ready   input dcdn; // Data Carrier Detect   input rin; // Ring indicator   input sin; // Serial Input   input lsreg_b0; // Line Status register bit 0   input lsreg11; // Line Status register bit1 enable   input lsreg_b2; // Line Status register bit 2   input lsreg_b3; // Line Status register bit 3   input lsreg_b4; // Line Status register bit 4   input lsreg51; // Line Status register bit 5 enable1   input lsreg_b7; // Line Status register bit 7   input temt; // Transmitter Fifo Empty   input fcreg11; // Fifo Control register bit 1 enable1   input fcreg21; // Fifo Control register bit 2 enable1   input thrint; // Transmitter Holding Register interrupt   input sout_org; // Internal Serial output signal   input[DATA_WIDTH - 1:0] d; // Data input bus   output thrint4; // Transmitter Holding Register interrupt enable4   wire thrint4;   output thrint5; // Transmitter Holding Register interrupt enable5   wire thrint5;   output sin_org; // Internal Serial input signal   reg sin_org;   output rtsn; // Request To send   reg rtsn;   output dtrn; // Data terminal ready   reg dtrn;   output out1n; // Ouput 1   reg out1n;   output out2n; // Ouput 2   reg out2n;   output sout; // Serial output   reg sout;   output[DATA_WIDTH - 1:0] dmreg; // MSB divisor register   reg[DATA_WIDTH - 1:0] dmreg;   output[DATA_WIDTH - 1:0] dlreg; // LSB divisor register   reg[DATA_WIDTH - 1:0] dlreg;   output[3:0] iereg; // Interrupt Enable register   reg[3:0] iereg;   output[DATA_WIDTH - 1:0] lcreg; // Line control register   reg[DATA_WIDTH - 1:0] lcreg;   output[DATA_WIDTH - 1:0] lsreg; // Line status register   wire[DATA_WIDTH - 1:0] lsreg;   output[4:0] mcreg; // Modem control register   wire[4:0] mcreg;   output[DATA_WIDTH - 1:0] msreg; // Modem status register   reg[DATA_WIDTH - 1:0] msreg;   output[5:0] fcreg; // Fifo Control register   wire[5:0] fcreg;   output[DATA_WIDTH - 1:0] sreg;    reg[DATA_WIDTH - 1:0] sreg;   reg cts_org;    reg dsr_org;    reg ri_org;    reg dcd_org;    reg prev_cts;    reg prev_dsr;    reg prev_ri;    reg prev_dcd;    reg lsreg10;    reg lsreg50;    reg fcreg20;    reg fcreg10;    reg lsreg02;    reg[5:0] fcreg_int;    wire[DATA_WIDTH - 1:0] lsreg_int;    reg[4:0] mcreg_int;    reg thrint4_int;    reg thrint5_int;    assign fcreg = fcreg_int ;    assign mcreg = mcreg_int ;    assign lsreg = lsreg_int ;    assign thrint4 = thrint4_int ;    assign thrint5 = thrint5_int ;    assign lsreg_int[0] = lsreg02 ^ lsreg_b0 ;    assign lsreg_int[1] = lsreg10 ^ lsreg11 ;    assign lsreg_int[2] = lsreg_b2 ;    assign lsreg_int[3] = lsreg_b3 ;    assign lsreg_int[4] = lsreg_b4 ;    assign lsreg_int[5] = ~(lsreg50 ^ lsreg51) ;    assign lsreg_int[6] = temt ;    assign lsreg_int[7] = lsreg_b7 ;    always @(fcreg10 or fcreg11)   begin      fcreg_int[1] = fcreg10 ^ fcreg11 ;   end   always @(fcreg20 or fcreg21)   begin      fcreg_int[2] = fcreg20 ^ fcreg21 ;   end   //------------------------   // Local loopback feature   //------------------------   always @(mcreg_int or sout_org or sin or ctsn or dsrn or rin or dcdn)   begin      if ((mcreg_int[4]) == 1'b1)      begin         // LOOP         sout <= 1'b1 ;          sin_org <= sout_org ;          msreg[4] <= mcreg_int[1] ;          msreg[5] <= mcreg_int[0] ;          msreg[6] <= mcreg_int[2] ;          msreg[7] <= mcreg_int[3] ;          rtsn <= 1'b1 ;          dtrn <= 1'b1 ;          out1n <= 1'b1 ;          out2n <= 1'b1 ;          dsr_org <= ~mcreg_int[0] ;          cts_org <= ~mcreg_int[1] ;          ri_org <= ~mcreg_int[2] ;          dcd_org <= ~mcreg_int[3] ;       end      else      begin         sout <= sout_org ;          sin_org <= sin ;          msreg[4] <= ~ctsn ;          msreg[5] <= ~dsrn ;          msreg[6] <= ~rin ;          msreg[7] <= ~dcdn ;          rtsn <= ~mcreg_int[1] ;          dtrn <= ~mcreg_int[0] ;          out1n <= ~mcreg_int[2] ;          out2n <= ~mcreg_int[3] ;          dsr_org <= dsrn ;          cts_org <= ctsn ;          ri_org <= rin ;          dcd_org <= dcdn ;       end    end    //---------------------------   // Interrupt enable register   //---------------------------   always @(posedge mr or negedge wr)   begin      if (mr == 1'b1)      begin         iereg <= {4{1'b0}} ;       end      else      begin         if (ena_ier == 1'b1)         begin            iereg <= d[3:0] ;          end       end    end    //-----------------------   // Line control register   //-----------------------   always @(posedge mr or negedge wr)   begin      if (mr == 1'b1)      begin         lcreg <= {1{1'b0}} ;       end      else      begin         if (ena_lcr == 1'b1)         begin            lcreg <= d ;          end       end    end    //--------------------------------------   // LINE STATUS register bit 1 resetting    //--------------------------------------   always @(posedge mr or posedge clk)   begin      if (mr == 1'b1)      begin         lsreg10 <= 1'b0 ;       end      else      begin         if (prevrdlsr == 1'b1 & rd == 1'b0 & (fcreg_int[1]) == 1'b0)         begin            lsreg10 <= lsreg11 ;          end       end    end    //--------------------------------------   // LINE STATUS register bit 5 resetting    //--------------------------------------   always @(posedge mr or negedge wr)   begin      if (mr == 1'b1)      begin         lsreg50 <= 1'b0 ;       end      else      begin         if (write_thr == 1'b1 & (lsreg_int[5]) == 1'b1)         begin            lsreg50 <= ~lsreg50 ;          end       end    end    //----------------------------   // MODEM control register   //----------------------------   always @(posedge mr or negedge wr)   begin      if (mr == 1'b1)      begin         mcreg_int <= {5{1'b0}} ;       end      else      begin         if (ena_mcr == 1'b1)         begin            mcreg_int <= d[4:0] ;          end       end    end    //------------------   // Scratch register   //------------------   always @(posedge mr or negedge wr)   begin      if (mr == 1'b1)      begin         sreg <= {1{1'b0}} ;       end      else      begin         if (ena_sr == 1'b1)         begin            sreg <= d ;          end       end    end    //----------------------------   // Divisor latch LSB register   //----------------------------   always @(posedge mr or negedge wr)   begin      if (mr == 1'b1)      begin         dlreg <= 8'b00000001 ;       end      else      begin         if (write_dlr == 1'b1)         begin            dlreg <= d ;          end       end    end    //----------------------------   // Divisor latch MSB register   //----------------------------   always @(posedge mr or negedge wr)   begin      if (mr == 1'b1)      begin         dmreg <= 8'b00000000 ;       end      else      begin         if (write_dmr == 1'b1)         begin            dmreg <= d ;          end       end    end    //----------------------------------------------------------------------   // Interrupt is enabled in the middle of interrupt (lsreg(5) = 1) will   // cause interrupt   //----------------------------------------------------------------------   always @(posedge mr or posedge clk)   begin      if (mr == 1'b1)      begin         thrint5_int <= 1'b0 ;       end      else      begin         if (ena_ier == 1'b1 & wr == 1'b1)         begin            if ((d[1]) == 1'b1 & thrint == 1'b0 & (lsreg_int[5]) == 1'b1)            begin               thrint5_int <= ~(thrint5_int) ;             end          end       end    end    //-----------------------   // FIFO control register   //-----------------------   always @(posedge mr or negedge wr)   begin      if (mr == 1'b1)      begin         fcreg_int[5:3] <= 3'b000 ;          fcreg_int[0] <= 1'b0 ;          fcreg20 <= 1'b0 ;          fcreg10 <= 1'b0 ;          thrint4_int <= 1'b0 ;          lsreg02 <= 1'b0 ;       end      else      begin         if (read_iir == 1'b1)         begin            if ((d[0]) == 1'b1)            begin               fcreg_int[5:4] <= d[DATA_WIDTH - 1:6] ;                fcreg_int[3] <= d[3] ;                fcreg_int[0] <= d[0] ;                // changing 16450 mode to FIFO mode will               // cause THRE (transmitter fifo empty) interrupt               if ((fcreg_int[0]) == 1'b0 & thrint == 1'b0)               begin                  thrint4_int <= ~(thrint4_int) ;                end                if ((d[2]) == 1'b1 & (fcreg_int[2]) == 1'b0)               begin                  fcreg20 <= ~fcreg20 ;                end                if ((d[1]) == 1'b1 & (fcreg_int[1]) == 1'b0)               begin                  fcreg10 <= ~fcreg10 ;                end             end            else            begin               fcreg_int[5:3] <= 3'b000 ;                fcreg_int[0] <= 1'b0 ;                // changing FIFO mode to 16450 mode will               // cause THRE interrupt               if ((fcreg_int[0]) == 1'b1 & thrint == 1'b0)               begin                  thrint4_int <= ~(thrint4_int) ;                end                if ((fcreg_int[0]) == 1'b1 & lsreg_b0 == 1'b1)               begin                  lsreg02 <= ~(lsreg02) ;                end                if ((fcreg_int[2]) == 1'b1)               begin                  fcreg20 <= ~fcreg20 ;                end                if ((fcreg_int[1]) == 1'b1)               begin                  fcreg10 <= ~fcreg10 ;                end             end          end       end    end    always @(posedge clk)   begin      prev_dsr <= dsr_org ;       prev_cts <= cts_org ;       prev_ri <= ri_org ;       prev_dcd <= dcd_org ;    end    //-------------------------------   // Indicate change in CTS signal   //-------------------------------   always @(posedge mr or posedge clk)   begin      if (mr == 1'b1)      begin         msreg[0] <= 1'b0 ;       end      else      begin         if ((cts_org == 1'b1 & prev_cts == 1'b0) | (cts_org == 1'b0 & prev_cts == 1'b1))         begin            msreg[0] <= 1'b1 ;          end         else if (read_msr == 1'b1)         begin            msreg[0] <= 1'b0 ;          end       end    end    //-------------------------------   // Indicate change in DSR signal   //-------------------------------   always @(posedge mr or posedge clk)   begin      if (mr == 1'b1)      begin         msreg[1] <= 1'b0 ;       end      else      begin         if ((dsr_org == 1'b1 & prev_dsr == 1'b0) | (dsr_org == 1'b0 & prev_dsr == 1'b1))         begin            msreg[1] <= 1'b1 ;          end         else if (read_msr == 1'b1)         begin            msreg[1] <= 1'b0 ;          end       end    end    //-------------------------------   // Indicate change in DCD signal   //-------------------------------   always @(posedge mr or posedge clk)   begin      if (mr == 1'b1)      begin         msreg[3] <= 1'b0 ;       end      else      begin         if ((dcd_org == 1'b1 & prev_dcd == 1'b0) | (dcd_org == 1'b0 & prev_dcd == 1'b1))         begin            msreg[3] <= 1'b1 ;          end         else if (read_msr == 1'b1)         begin            msreg[3] <= 1'b0 ;          end       end    end    //-----------------------------------   // Indicate rising edge in RI signal   //-----------------------------------   always @(posedge mr or posedge clk)   begin      if (mr == 1'b1)      begin         msreg[2] <= 1'b0 ;       end      else      begin         if (ri_org == 1'b1 & prev_ri == 1'b0)         begin            msreg[2] <= 1'b1 ;          end         else if (read_msr == 1'b1)         begin            msreg[2] <= 1'b0 ;          end       end    end endmodule

⌨️ 快捷键说明

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