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

📄 uart_51.v

📁 符合8051协议规范的UART的Verilog源代码.该压缩包是一个modelsim的工程.
💻 V
字号:
module uart_51(clk,rst,wr,wr_bit,addr,bit_in,data_in,t1_ow,rxd,txd,intr,data_out,pcon,scon,rx_sbuf);
input clk;
input rst;
input wr;
input wr_bit;
input [7:0] addr;
input bit_in;
input [7:0] data_in;
input t1_ow;
input rxd;

output txd;
output intr;
output [7:0] data_out;
output [7:0] scon;
output [7:0] pcon;
output [7:0] rx_sbuf;
reg txd;
reg [7:0] scon;
reg [7:0] pcon;

assign intr=scon[1]|scon[0];
//
wire t1_ow_final;
reg div2_flag;
reg t1_ow_buf;
reg t1_ow_final_buf;
// signals with transmit part
reg [7:0] tx_sbuf;
reg send_n;  //active low,indicate that it is transmiting datas
wire wr_sbuf_en;
assign wr_sbuf_en=(wr==1'b1&&addr==8'h99);
reg wr_sbuf_en_mem;
wire shift_en;
reg [3:0] tx_next_state;
reg [3:0] tx_current_state;


parameter IDLE=11,START=0,D0=1,D1=2,D2=3,D3=4,D4=5,D5=6,D6=7,D7=8,TB8_BIT=9,STOP_BIT=10; //states define
  
reg [3:0] osc_cnt;
reg [3:0] tx_sample_cnt;
reg tx_clk;
//signals with receive part
reg [3:0] rx_next_state;
reg [3:0] rx_current_state;
reg [3:0] rx_sample_cnt;
wire one_bit;
reg rxd_buf;
reg [10:0] sbuf_rxd_tmp;
reg [7:0] rx_sbuf;
reg sample_7,sample_8,sample_9;
reg receive;
//signals with both transmiting and receiving parts
//always @(*)
//begin
//SM0=scon[7];
//SM1=scon[6];
//SM2=scon[5];
//REN=scon[4];
//TB8=scon[3];
//RB8=scon[2];
//TI=scon[1];
//RI=scon[0];
//end

always @(posedge clk or posedge rst)       //register scon
begin
  if (rst)
    scon <=8'b0100_0000;
  else if ((wr) & !(wr_bit) & (addr==8'h98))
    scon <=data_in;
  else if ((wr) & (wr_bit) & (addr[7:3]==5'b10011))
    scon[addr[2:0]]<=bit_in;
  else if (tx_next_state==STOP_BIT)
    scon[1] <=1'b1;
  else 
  case(rx_next_state)
  START:scon[0]<=1'b0;
  IDLE:if(rx_current_state==STOP_BIT) 
  begin
	  case (scon[7:6])
	   2'b00: scon[0] <= 1'b1;
	   2'b01: if(scon[5]) 
	             if(one_bit)
	             scon[0] <= 1'b1;
	             else
	             scon[0] <= 1'b0;
	          else
	             scon[0] <= 1'b1;
	   2'b10,2'b11: if(scon[5])
	                  scon[0]<=sbuf_rxd_tmp[9];
	                else
	                scon[0]=1'b1; 
	  endcase
  end
  endcase
end

//
//power control register
//
wire smod;
assign smod = pcon[7];
always @(posedge clk or posedge rst)
begin
  if (rst)
    pcon <= 8'b0000_0000;
  else if ((addr==8'h87) & (wr) & !(wr_bit))
    pcon <= data_in;
end

always @(posedge clk or posedge rst)   //osc_cnt 
if(rst)
osc_cnt<=4'b0000;
else if(osc_cnt==4'b1011)
osc_cnt<=4'b0000;
else
osc_cnt<=osc_cnt+1'b1;

always @(posedge clk or posedge rst)   //t1_ow_buf 
if(rst)
t1_ow_buf<=1'b0;
else if(t1_ow)
t1_ow_buf<=~t1_ow;

always @(posedge clk or posedge rst)   //div2_flag 
if(rst)
div2_flag<=1'b0;
else if(~t1_ow_buf&t1_ow)
div2_flag<=~div2_flag;

assign t1_ow_final=(pcon[7]==1'b1)?t1_ow:t1_ow&div2_flag;

//transmit part
always @(posedge clk or posedge rst)  //t1_ow_final_buf
if(rst) t1_ow_final_buf<=1'b0;	
else    t1_ow_final_buf<=t1_ow_final;
	
always @(posedge clk or posedge rst)  //tx_sample_cnt
if(rst)
	begin
	tx_sample_cnt<=4'b0000;
	end	
else if(t1_ow_final_buf==1'b0&&t1_ow_final==1'b1)
	tx_sample_cnt<=tx_sample_cnt+1'b1;

always @(posedge clk or posedge rst)
if(rst)
wr_sbuf_en_mem<=1'b0;
else if (wr_sbuf_en&&wr_sbuf_en_mem<=1'b0)
wr_sbuf_en_mem<=1'b1; //represent that the tx_sbuf has been loaded
else if(tx_current_state==STOP_BIT)
wr_sbuf_en_mem<=1'b0;

assign shift_en=wr_sbuf_en_mem==1'b1&&tx_sample_cnt==4'b1111&&osc_cnt==4'b1011&&t1_ow_final_buf==1'b0&&t1_ow_final==1'b1;
always @(posedge clk or posedge rst)
if(rst)
tx_sbuf<=8'b0000_0000;
else if (wr_sbuf_en&&wr_sbuf_en_mem<=1'b0) 
tx_sbuf<=data_in;
else if(send_n==1'b0&&shift_en)
tx_sbuf<=tx_sbuf>>1'b1;

//the three always phrase below is the 3 parts discription of state machine

always @(*)//(tx_current_state or wr_sbuf_en_mem or tx_sample_cnt or osc_cnt or TH1 or TL1 or shift_en)
begin
case(tx_current_state)
IDLE: if(shift_en)  //
      tx_next_state=START;
      else
      tx_next_state= IDLE;
START:if(shift_en)
      tx_next_state=D0;
      else
      tx_next_state=START;
D0:  if(shift_en)
      tx_next_state=D1;
      else
      tx_next_state=D0;
D1:  if(shift_en)
      tx_next_state=D2;
      else
      tx_next_state=D1;
D2:  if(shift_en)
      tx_next_state=D3;
      else
      tx_next_state=D2;
D3:  if(shift_en)
      tx_next_state=D4;
      else
      tx_next_state=D3;
D4:  if(shift_en)
      tx_next_state=D5;
      else
      tx_next_state=D4;
D5:  if(shift_en)
      tx_next_state=D6;
      else
      tx_next_state=D5;
D6:  if(shift_en)
      tx_next_state=D7;
      else
      tx_next_state=D6;
D7:  if(shift_en)
         if(scon[7:6]==2'b00||scon[7:6]==2'b01)
         tx_next_state=STOP_BIT;
         else
         tx_next_state=TB8_BIT;
     else
     tx_next_state=D7;
TB8_BIT:  tx_next_state=STOP_BIT;
STOP_BIT: if(tx_sample_cnt==4'b1111&&osc_cnt==4'b1011&&t1_ow_final==1'b1)
       	  tx_next_state=IDLE;
       	  else
       	  tx_next_state=STOP_BIT;
       
default:tx_next_state=IDLE;
endcase
end


always @(posedge clk or posedge rst)
if(rst)
tx_current_state<=IDLE;
else
tx_current_state<=tx_next_state;


always @(posedge clk or posedge rst)
if(rst)
begin
txd<=1'b1;
send_n<=1'b1;
end
else
case(tx_next_state)
IDLE: 
      begin
      send_n<=1'b1;
      txd<=1'b1;
      end
START:begin
      send_n<=1'b0;
      txd<=1'b0;
      end
D0:  txd<=tx_sbuf[0];
D1:  txd<=tx_sbuf[0];
D2:  txd<=tx_sbuf[0];
D3:  txd<=tx_sbuf[0];
D4:  txd<=tx_sbuf[0];
D5:  txd<=tx_sbuf[0];
D6:  txd<=tx_sbuf[0];
D7:  txd<=tx_sbuf[0];
TB8_BIT: txd<=scon[3];
STOP_BIT:
     begin
     txd<=1'b1;
     end
endcase

//receiving part
assign rx_shift_en=rx_sample_cnt==4'b1111&&t1_ow_final_buf==1'b0&&t1_ow_final==1'b1;
always @(posedge clk or posedge rst)         //describe the rxd_buf
if(rst)
rxd_buf<=1'b0;
else
rxd_buf<=rxd;

always @(posedge clk or posedge rst)          //describe the rx_sample_cnt
if(rst)
rx_sample_cnt<=4'b0000;
else if(rxd_buf==1'b1&&rxd==1'b0)            //此条件启动接收过程
rx_sample_cnt<=4'b0000;
else if(t1_ow_final)
rx_sample_cnt<=rx_sample_cnt+1'b1;

always @(posedge clk)
if(rx_sample_cnt==4'b0110&&t1_ow_final)
sample_7<=rxd;

always @(posedge clk)
if(rx_sample_cnt==4'b0111&&t1_ow_final)
sample_8<=rxd;

always @(posedge clk)
if(rx_sample_cnt==4'b1000&&t1_ow_final)
sample_9<=rxd;

assign one_bit=sample_7&&sample_8||sample_7&&sample_9||sample_8&&sample_9;
//the three always phrase below is the 3 parts discription of state machine

always @(*)
begin
case(rx_current_state)
IDLE: if(rxd_buf==1'b1&&rxd==1'b0&&scon[4]==1'b1)  //检测到了rxd从1到0的跳变
      rx_next_state=START;
      else
      rx_next_state= IDLE;
START: if(rx_shift_en)
         if(~one_bit)
          rx_next_state=D0;
         else 
          rx_next_state=IDLE;              
       else
       rx_next_state=START;

D0:  if(rx_shift_en)
      rx_next_state=D1;
      else
      rx_next_state=D0;
D1:  if(rx_shift_en)
      rx_next_state=D2;
      else
      rx_next_state=D1;
D2:  if(rx_shift_en)
      rx_next_state=D3;
      else
      rx_next_state=D2;
D3:  if(rx_shift_en)
      rx_next_state=D4;
      else
      rx_next_state=D3;
D4:  if(rx_shift_en)
      rx_next_state=D5;
      else
      rx_next_state=D4;
D5:  if(rx_shift_en)
      rx_next_state=D6;
      else
      rx_next_state=D5;
D6:  if(rx_shift_en)
      rx_next_state=D7;
      else
      rx_next_state=D6;
D7:  if(rx_shift_en)
         if(scon[7:6]==2'b00||scon[7:6]==2'b01)
         rx_next_state=STOP_BIT;
         else
         rx_next_state=TB8_BIT;
     else rx_next_state=D7;
TB8_BIT:  if(rx_shift_en)
	    rx_next_state=STOP_BIT;
	  else
	    rx_next_state=TB8_BIT;  
STOP_BIT: if(rx_shift_en)
       rx_next_state=IDLE;
       else
       rx_next_state=STOP_BIT;
endcase
end


always @(posedge clk or posedge rst)
if(rst)
rx_current_state<=IDLE;
else
rx_current_state<=rx_next_state;


always @(posedge clk or posedge rst)
if(rst)
receive<=1'b0;
else
case(rx_next_state)
IDLE: 
	receive<=1'b0;
START:begin
	receive<=1'b1;
	sbuf_rxd_tmp<=10'b11_1111_1111;
      end
D0,D1,D2,D3,D4,D5,D6,D7:  if(rx_shift_en) sbuf_rxd_tmp<={sbuf_rxd_tmp[10:0],one_bit};
STOP_BIT:
     receive<=1'b1;    // end of receiving
endcase

//
//serial port buffer (receive)
//

always @(posedge clk or posedge rst)
begin
  if (rst)
    rx_sbuf<=8'h00;
  else if (rx_next_state==STOP_BIT) 
    case (scon[7:6]) 
      2'b00,2'b01:rx_sbuf<=sbuf_rxd_tmp[7:0];
      2'b10,2'b11:rx_sbuf<=sbuf_rxd_tmp[8:1];
    endcase
end


endmodule

⌨️ 快捷键说明

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