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

📄 mp_int.v

📁 Verilog实现mini-uart
💻 V
字号:
//============================================================================
//
//        Title     : UART INTERFACE DESIGN
//        Author    : JP LIU
//
//=============================================================================
//
//        File Name      : mp_int.v
//        Module Name    : mp_int
//
//=============================================================================
//
// Microprocessor Interface module
// This module provides the interface between the uart receiver and transmitter 
//and the microprocessor bus
//
// Register Map
//
// Address  Mode  Name             Desc
// 000      W     XMIT_DAT_REG     When data is written to this reg,
// 000      R     REC_DAT_REG
// 001      R/W   BAUD_REG_LO
// 010      R/W   BAUD_REG_HI
// 011      R     STAT_REG         0 = Xmit Busy. 
//                                     Set when new data is written to the
//                                     transmit data register.  Cleared when
//                                     transmitter is done transmitting.  
//                                 1 = Rec Data Available. Set when new data is 
//                                     received from receiver. Cleared when MP
//                                     reads from the read register 
//                                 2 =
//                                 3 =
//                                 4 =
//                                 5 =
//                                 6 =
//                                 7 =
// 100      R/W   INT_STAT_REG     Interrupt status register
//                                 Write 1 to clear the specific bits
//                                 0 =
//                                 1 =
//                                 2 =
//                                 3 =
//                                 4 =
//                                 5 =
//                                 6 =
//                                 7 =
// 101      R/W   INT_ENA_REG      Interrupt enable register
//
//=============================================================================

`include "uart_inc.h"

module mp_int 
(
  // Output Port
  START_PULSE,
  REG_XMIT_DAT,
  BAUD_RATE_DIV,
  MP_DATA_FROM_UART,
  MP_INT_B,

  // Input Port
  SYS_RST_B,
  UART_CLK,
  MP_CLK,
  MP_CS_B,
  MP_ADDX,
  MP_DATA_TO_UART,
  MP_RD_B,
  MP_WR_B,
  XMIT_DONE,
  REC_DATA,
  REC_READY
);


////////////////////////////////////////////// 
//
// INPUT AND OUTPUT DECLARATION             //
//
//////////////////////////////////////////////


output        START_PULSE;
output [7:0]  REG_XMIT_DAT;
output [15:0] BAUD_RATE_DIV;
output [7:0]  MP_DATA_FROM_UART;
output        MP_INT_B;

input         SYS_RST_B;
input         UART_CLK;
input         MP_CLK;
input         MP_CS_B;
input  [2:0]  MP_ADDX;
input  [7:0]  MP_DATA_TO_UART;
input         MP_RD_B;
input         MP_WR_B;
input         XMIT_DONE;
input  [7:0]  REC_DATA;
input         REC_READY;

/////////////////////////////////////////////
//
// WIRE AND REG DECLARATION                //
//
/////////////////////////////////////////////

wire          START_PULSE;
wire   [7:0]  MP_DATA_FROM_UART;
wire          MP_INT_B;
wire   [15:0] BAUD_RATE_DIV;

wire          SYS_RST_B;
wire          UART_CLK;
wire          MP_CLK;
wire          MP_CS_B;
wire   [2:0]  MP_ADDX;
wire   [7:0]  MP_DATA_TO_UART;
wire          MP_RD_B;
wire          MP_WR_B;
wire          XMIT_DONE;
wire   [7:0]  REC_DATA;
wire          REC_READY;

reg    [7:0]  REG_XMIT_DAT;

wire   [7:0]  MP_DATA;
wire          SEL_BAUD_REGLO;
wire          SEL_BAUD_REGHI;
wire          SEL_XMIT_DAT;
wire          SEL_INT_MASK;
wire          SEL_INT_STAT_REG;
wire          XMIT_BUSY_RST;
wire          XMIT_BUSY_SYNC;
wire          XMIT_DONE_SYNC;
wire          REC_READY_SYNC;
wire          REC_READY_PULSE;
wire          WR_DONE_PULSE;

reg    [7:0]  REG_BAUD_RATE_DIV_LO_IN;
reg    [7:0]  REG_BAUD_RATE_DIV_LO;
reg    [7:0]  REG_BAUD_RATE_DIV_HI;
reg    [7:0]  REG_INT_ENA;
reg           XMIT_BUSY;
reg           REC_NEW_DATA;
reg           STAT_REC_DATA;
reg           STAT_XMIT_EMPTY;
reg    [7:0]  MP_DATA_OUT;

/////////////////////////////////////////////
//  SEQUENCAL LOGIC                        //
/////////////////////////////////////////////

assign MP_DATA           = MP_DATA_TO_UART;
assign MP_DATA_FROM_UART = MP_DATA_OUT;

assign BAUD_RATE_DIV     = {REG_BAUD_RATE_DIV_HI,REG_BAUD_RATE_DIV_LO};

assign SEL_BAUD_REGLO    = ~MP_CS_B && (MP_ADDX==SEL_BAUD_REG_LO);
assign SEL_BAUD_REGHI    = ~MP_CS_B && (MP_ADDX==SEL_BAUD_REG_HI);
assign SEL_XMIT_DAT      = ~MP_CS_B && (MP_ADDX==SEL_XMIT);
assign SEL_INT_MASK      = ~MP_CS_B && (MP_ADDX==SEL_INT_ENA);
assign SEL_INT_STAT_REG  = ~MP_CS_B && (MP_ADDX==SEL_INT_STAT);

assign MP_INT_B          =~((STAT_XMIT_EMPTY && REG_INT_ENA[0]) || (STAT_REC_DATA && REG_INT_ENA[1]));

always @(posedge MP_CLK or negedge SYS_RST_B)
 if (~SYS_RST_B) 
     begin
       REG_BAUD_RATE_DIV_LO <= #1 0;
       REG_BAUD_RATE_DIV_HI <= #1 0;   
       REG_XMIT_DAT         <= #1 0;
       REG_INT_ENA          <= #1 0;
     end 
 else 
     begin
       if (~MP_WR_B) 
           begin
              if (SEL_BAUD_REGLO)
                     REG_BAUD_RATE_DIV_LO_IN <= #1 MP_DATA;
              if (SEL_BAUD_REGHI) 
                  begin
                     REG_BAUD_RATE_DIV_HI <= #1 MP_DATA;
                     REG_BAUD_RATE_DIV_LO <= #1 REG_BAUD_RATE_DIV_LO_IN;
                  end
              if (SEL_XMIT_DAT)   
                     REG_XMIT_DAT  <= #1 MP_DATA;
              if (SEL_INT_MASK)   
                     REG_INT_ENA   <= #1 MP_DATA;   
          end
     end

always @(MP_ADDX or REC_DATA or REG_BAUD_RATE_DIV_LO or 
         REG_BAUD_RATE_DIV_HI or STAT_REC_DATA or STAT_XMIT_EMPTY or 
         REG_INT_ENA or REC_NEW_DATA or XMIT_BUSY )
    case (MP_ADDX)
      SEL_REC_DAT:     MP_DATA_OUT = REC_DATA;
      SEL_BAUD_REG_LO: MP_DATA_OUT = REG_BAUD_RATE_DIV_LO;
      SEL_BAUD_REG_HI: MP_DATA_OUT = REG_BAUD_RATE_DIV_HI;
      SEL_STAT_REG:    MP_DATA_OUT = {REC_NEW_DATA,XMIT_BUSY};
      SEL_INT_STAT:    MP_DATA_OUT = {STAT_REC_DATA,STAT_XMIT_EMPTY};
      SEL_INT_ENA:     MP_DATA_OUT = REG_INT_ENA;
      default:         MP_DATA_OUT = 8'Hxx;
    endcase

always @(posedge MP_CLK or negedge SYS_RST_B)
   if (~SYS_RST_B) 
      begin
        STAT_REC_DATA <= #1 1'B0 ;
        STAT_XMIT_EMPTY <= #1 1'B1;
      end
   else
      begin
        if (SEL_INT_STAT_REG && ~MP_WR_B)
              STAT_XMIT_EMPTY <= #1 MP_DATA[0];
        else if (XMIT_BUSY_RST)
              STAT_XMIT_EMPTY <= #1 1'B1;
        else if (SEL_XMIT_DAT && ~MP_WR_B)
              STAT_XMIT_EMPTY <= #1 1'B0;
        if (SEL_INT_STAT_REG && ~MP_WR_B)
              STAT_REC_DATA <= #1 MP_DATA[1];
        else if (REC_READY_PULSE)
              STAT_REC_DATA <= #1 1'B1;        else if (SEL_XMIT_DAT && ~MP_RD_B)
              STAT_REC_DATA <= #1 1'B0;
      end

always @(posedge MP_CLK or negedge SYS_RST_B)
   if (~SYS_RST_B) 
         REC_NEW_DATA <= #1 1'B0;
   else if (REC_READY_PULSE)
         REC_NEW_DATA <= #1 1'B1;
   else if (SEL_XMIT_DAT && MP_RD_B)
         REC_NEW_DATA <= #1 1'B0;

always @(posedge MP_CLK or negedge SYS_RST_B)
   if (~SYS_RST_B)
         XMIT_BUSY <= #1 1'B0;
   else if (~XMIT_DONE_SYNC)
         XMIT_BUSY <= #1 1'B0;
   else if (WR_DONE_PULSE && SEL_XMIT_DAT)
         XMIT_BUSY <= #1 1'B1;
   
ONE_SHOT I_ONT_SHOT_0 (
                      .Q              (WR_DONE_PULSE),                 
                      .SYS_RST_B      (SYS_RST_B),
                      .CLK_IN         (MP_CLK),
                      .D              (MP_WR_B)
                      );

ONE_SHOT I_ONT_SHOT_1 (
                      .Q              (START_PULSE),                 
                      .SYS_RST_B      (SYS_RST_B),
                      .CLK_IN         (UART_CLK),
                      .D              (XMIT_BUSY_SYNC)
                      );

ONE_SHOT I_ONT_SHOT_2 (
                      .Q              (XMIT_BUSY_RST),                 
                      .SYS_RST_B      (SYS_RST_B),
                      .CLK_IN         (MP_CLK),
                      .D              (XMIT_DONE_SYNC)
                      );

ONE_SHOT I_ONT_SHOT_3 (
                      .Q              (REC_READY_PULSE),                 
                      .SYS_RST_B      (SYS_RST_B),
                      .CLK_IN         (MP_CLK),
                      .D              (REC_READY_SYNC)
                      );

SYNC I_SYNC_0 (
                .Q              (XMIT_BUSY_SYNC),
                .CLK_IN         (UART_CLK),
                .SYS_RST_B      (SYS_RST_B),
                .D              (XMIT_BUSY)
              );

SYNC I_SYNC_1 (
              .Q              (XMIT_DONE_SYNC),
              .CLK_IN         (MP_CLK),
              .SYS_RST_B      (SYS_RST_B),
              .D              (XMIT_DONE)
              );

SYNC I_SYNC_2 (
              .Q              (REC_READY_SYNC),
              .CLK_IN         (MP_CLK),
              .SYS_RST_B      (SYS_RST_B),
              .D              (REC_READY)
              );`endprotect

endmodule

⌨️ 快捷键说明

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