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

📄 mp_int.v

📁 一个小的UART,可以做为设计参考
💻 V
字号:

//
// MP_INT.v
//
// Microprocessor Interface module
// This module provides the interface between
// the uart receiver and transmitter and the 
// the microprocessor bus
//
// log:
// 8/7/01  Added more registers
//

module mp_int (
			// system connection
			sys_rst_l,
            uart_clk,
			mp_clk,

			// micro processor conenction
			mp_cs_l,
			mp_addx,
			mp_data_to_uart,
			mp_data_from_uart,
			mp_rd_l,
			mp_wr_l,
            mp_int_l,

			// to / from internal modules
			baud_rate_div,

            // from uart XMITTER
            start_pulseH,
            xmit_doneH,
			reg_xmit_dat,
			xmit_busyH,

            // uart RECEIVER
            rec_dataH,
            rec_readyH

            ,
            xmit_busy_rstH,
            stat_xmit_emptyH,
            stat_rec_dataH,
            wr_done_pulseH,
            sel_xmit_datH
			);

`include "uart_inc.h"

// 
// 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
//

input			sys_rst_l;
input			mp_clk;
input           uart_clk;
input			mp_cs_l;
input	[2:0]	mp_addx;
input			mp_rd_l;
input			mp_wr_l;
input	[7:0]	mp_data_to_uart;
output	[7:0]	mp_data_from_uart;
output	[15:0]	baud_rate_div;
output          start_pulseH;
input           xmit_doneH;
output          xmit_busyH;
output  [7:0]   reg_xmit_dat;
input   [7:0]   rec_dataH;
input           rec_readyH;
output          mp_int_l;

//debug
output          xmit_busy_rstH;
output          stat_xmit_emptyH;
output          stat_rec_dataH;
output          wr_done_pulseH;
output          sel_xmit_datH;


reg		[7:0]	reg_baud_rate_div_lo_in;
reg		[7:0]	reg_baud_rate_div_hi;
reg     [7:0]   reg_baud_rate_div_lo;
reg		[7:0]	reg_xmit_dat;
reg     [7:0]   reg_int_ena;
reg             xmit_busyH;
reg             xmit_busy_rstH;
reg     [7:0]   mp_data_out;
reg             stat_rec_dataH;
reg             stat_xmit_emptyH;
reg             rec_new_dataH;

wire	[7:0]	mp_data;
wire			sel_baud_regLoH;
wire			sel_baud_regHiH;
wire 			sel_xmit_datH;
wire            sel_int_maskH;
wire            wr_done_pulseH;
wire            xmit_busyH_sync;
wire			start_pulseH;
wire            xmit_doneH_sync;
wire	[15:0]	baud_rate_div;
wire            xmit_busy_rstL;
wire            mp_data_out_enaH;
wire            rec_readyH_sync;
wire            rec_ready_pulseH;
wire            sel_int_stat_regH;

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_regLoH = ~mp_cs_l & (mp_addx == SEL_BAUD_REG_LO);
assign sel_baud_regHiH = ~mp_cs_l & (mp_addx == SEL_BAUD_REG_HI);
assign sel_xmit_datH   = ~mp_cs_l & (mp_addx == SEL_XMIT_DAT);
assign sel_int_maskH   = ~mp_cs_l & (mp_addx == SEL_INT_ENA_REG);
assign sel_int_stat_regH  = ~mp_cs_l & (mp_addx == SEL_INT_STAT_REG);

//
// Register File
// Accessible by the host micro
//
always @(posedge mp_clk or negedge sys_rst_l)
 if (~sys_rst_l) begin
   reg_baud_rate_div_lo <= 0;
   reg_baud_rate_div_hi <= 0;   
   reg_xmit_dat         <= 0;
   reg_int_ena         <= 0;
 end else begin
   if (~mp_wr_l) begin
     if (sel_baud_regLoH) reg_baud_rate_div_lo_in <= mp_data;
     if (sel_baud_regHiH) begin
           reg_baud_rate_div_hi <= mp_data;
           reg_baud_rate_div_lo <= reg_baud_rate_div_lo_in;
     end
     if (sel_xmit_datH)   reg_xmit_dat  <= mp_data;
     if (sel_int_maskH)   reg_int_ena   <= mp_data;   
   end
 end


// output mux
always @(mp_addx or rec_dataH or reg_baud_rate_div_lo or 
         reg_baud_rate_div_lo or stat_rec_dataH or stat_xmit_emptyH or 
         reg_int_ena )
begin
  case (mp_addx)
    SEL_REC_DAT:     mp_data_out = rec_dataH;
    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_dataH,xmit_busyH};
    SEL_INT_STAT_REG:mp_data_out = {stat_rec_dataH,stat_xmit_emptyH};
    SEL_INT_ENA_REG: mp_data_out = reg_int_ena;
    default:         mp_data_out = 8'hxx;
  endcase

end

// Interrupt generation
//
// Interrupt is generated only if the 
// associated status signal is on and the enable bit is 
// set.  Once the interrupt is generated, it can only
// be cleared if all of the status bits (anded with its enable) 
// are cleared 
//
assign mp_int_l= ~( ( stat_xmit_emptyH & reg_int_ena[0] ) |
                    ( stat_rec_dataH   & reg_int_ena[1] )   );


// rec_new_dataH bit generation
// this is a bit which is set whenever a 
// new data has been received from the UART receiver
// it is clered when the host reads from the 
// read data register.
// Note that this is different from the stat_rec_dataH 
// which is set when thre is a new read data, and cleared
// by the host.
always @(posedge mp_clk or negedge sys_rst_l)
  if (~sys_rst_l) rec_new_dataH <= 0;
  else if (rec_ready_pulseH)        rec_new_dataH <= 1'b1;
  else if (sel_xmit_datH & mp_rd_l) rec_new_dataH <= 1'b0;
  

// Status register
always @(posedge mp_clk or negedge sys_rst_l)
  if (~sys_rst_l)  begin
     stat_rec_dataH   <= 1'b0;
     stat_xmit_emptyH  <= 1'b1;  // by default there is no data
  end else begin
     // the xmit_empty is set when the UART transmitter has
     // finished transmitting data.  It is cleared by the
     // micro
     if (sel_int_stat_regH & ~mp_wr_l) stat_xmit_emptyH <= mp_data[0];
     // set the flag, when the UART xmit is done
     else if (xmit_busy_rstH) stat_xmit_emptyH <= 1'b1;
     // cleared when a new data is sent to the UART
     else if (sel_xmit_datH & ~mp_wr_l) stat_xmit_emptyH <= 0;

     // the stat_rec_dataH is set whenever a new data is received
     // from the UART receiver.  It is cleared by the MP     
     if (sel_int_stat_regH & ~mp_wr_l) stat_rec_dataH <= mp_data[1];
     else if (rec_ready_pulseH) stat_rec_dataH <= 1'b1;

  end


assign xmit_busy_rstL = ~xmit_busy_rstH;

// instantiate a one-shot 
one_shot OS_WR (.clk_in(mp_clk), 
                .d(mp_wr_l),
                .q(wr_done_pulseH) );

// generate xmit_busyH
// this 'xmit_busyH' is set whenever a write to
// the xmit regiter is made.  It is then cleared when
// the uart trasmitter has finished its transmission
wire rst = sys_rst_l & xmit_busy_rstL;
always @(posedge mp_clk or negedge xmit_busy_rstL)
  if (~xmit_busy_rstL) xmit_busyH <= 0;
  else if (wr_done_pulseH & sel_xmit_datH)
     xmit_busyH <= 1;

// synchronizer
sync SYNC_WR (.clk_in(uart_clk),
              .sys_rst_l(xmit_busy_rstL),
              .d(xmit_busyH),
              .q(xmit_busyH_sync) );

// one - shot 
one_shot OS_WR2 (.clk_in(uart_clk),
                 .sys_rst_l(sys_rst_l),
                 .d(xmit_busyH_sync),
                 .q(start_pulseH) );


// ----
// 
sync SYNC_WR2 (.clk_in(mp_clk),
               .sys_rst_l(sys_rst_l),
               .d(xmit_doneH),
               .q(xmit_doneH_sync) );
               
// one shot 
one_shot OS_WR3 (.clk_in(mp_clk),
                 .sys_rst_l(sys_rst_l),
                 .d(xmit_doneH_sync),
                 .q(xmit_busy_rstH) );


//
// Synchronizer  and one shot for RECEIVE DATA READY signal
//

// dual rank synchronizer
sync SYNC_RECDAT (.clk_in(mp_clk),
                  .sys_rst_l(sys_rst_l),
                  .d(rec_readyH),
                  .q(rec_readyH_sync) );

// one shot
one_shot OS_RECDAT (.clk_in(mp_clk),
                    .sys_rst_l(sys_rst_l),
                    .d(rec_readyH_sync),
                    .q(rec_ready_pulseH) );

endmodule

⌨️ 快捷键说明

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