国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

基于FPGA的UART多字節(jié)環(huán)回實驗verilog代碼(含幀頭幀尾和解碼部分)

這篇具有很好參考價值的文章主要介紹了基于FPGA的UART多字節(jié)環(huán)回實驗verilog代碼(含幀頭幀尾和解碼部分)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

采用VIVADO開發(fā)環(huán)境,頻率50MHz,波特率 256000,8位數(shù)據(jù)位,1位停止位。

串口接收程序源自正點原子的例程。

帶仿真工程,數(shù)據(jù)幀格式如下圖:

fpga uart代碼,FPGA,fpga開發(fā)

發(fā)送數(shù)據(jù)為:aa ff 03 00 0E 03 B1 86 10 00 40 01 11 00 00 00 00 00 00 00 11 00 00 00 00 00 11 11 55 CC

效果如圖:

fpga uart代碼,FPGA,fpga開發(fā)

?仿真效果圖:

fpga uart代碼,FPGA,fpga開發(fā)

參考以下文章和視頻:?

FPGA串口多字節(jié)收發(fā)_嗶哩嗶哩_bilibili

FPGA串口多字節(jié)接收、解碼和仿真_淺塘.小鯉魚的博客-CSDN博客

完整工程代碼:

鏈接:https://pan.baidu.com/s/1c1GAXMzRUS1D3GdkSeK-7A?pwd=8888?
提取碼:8888?
復制這段內(nèi)容后打開百度網(wǎng)盤手機App,操作更方便哦

頂層模塊代碼如下:

`timescale 1ns / 1ps
//不同數(shù)據(jù)格式需要改波特率、發(fā)送模塊中的cnt閾值和環(huán)回模塊中的cnt閾值、接收模塊環(huán)回模塊中的幀頭幀尾判斷及DATA_NUM
module uart_loopback_top(
    input           sys_clk,            //外部50M時鐘
    input           sys_rst_n,          //外部復位信號,低有效
//(*mark_debug = "true"*)
    input           uart_rxd,           //UART接收端口
    output          uart_txd            //UART發(fā)送端口
   // output  [63:0]  dataA,              //數(shù)據(jù)包1
   // output  [63:0]  dataB,              //數(shù)據(jù)包2
   // output  [63:0]  dataC               //數(shù)據(jù)包3
    
      
    );

//parameter define
parameter  CLK_FREQ = 50000000;         //定義系統(tǒng)時鐘頻率
parameter  UART_BPS = 256000;           //定義串口波特率

//wire define   
//(*mark_debug = "true"*)
wire       uart_done;                   //UART單字節(jié)接收完成
wire       uart_recv_done;              //UART一幀接收完成
wire [7:0] uart_data;                   //UART單字節(jié)接收數(shù)據(jù)
wire       uart_send_en;                //UART發(fā)送使能
wire [7:0] uart_send_data;              //UART發(fā)送數(shù)據(jù)
wire       uart_tx_busy;                //UART發(fā)送忙狀態(tài)標志
wire [7:0] cnt;


//*****************************************************
//**                    main code
//*****************************************************

//串口接收模塊     
//uart_recv #(                          
//    .CLK_FREQ       (CLK_FREQ),         //設置系統(tǒng)時鐘頻率
//    .UART_BPS       (UART_BPS))         //設置串口接收波特率
//u_uart_recv(                 
//    .sys_clk        (sys_clk), 
//    .sys_rst_n      (sys_rst_n),
    
//    .uart_rxd       (uart_rxd),
//    .uart_done      (uart_recv_done),
//    .uart_data      (uart_recv_data)
//    );

//串口環(huán)回模塊    
//uart_loop u_uart_loop(
//    .sys_clk        (sys_clk),             
//    .sys_rst_n      (sys_rst_n),           
   
//    .recv_done      (uart_recv_done),   //接收一幀數(shù)據(jù)(30字節(jié)數(shù)據(jù))完成標志信號,4字節(jié)幀頭,3*8=24字節(jié)數(shù)據(jù),2字節(jié)幀尾
//    .recv_data      (uart_recv_data),   //接收的數(shù)據(jù)
   
//    .tx_busy        (uart_tx_busy),     //發(fā)送忙狀態(tài)標志      
//    .send_en        (uart_send_en),     //發(fā)送使能信號
//    .send_data      (uart_send_data)    //待發(fā)送數(shù)據(jù)
//    );

//串口接收模塊     
uart_recv #(                          
    .CLK_FREQ       (CLK_FREQ),         //設置系統(tǒng)時鐘頻率
    .UART_BPS       (UART_BPS))         //設置串口接收波特率
u_uart_recv(                 
    .sys_clk        (sys_clk), 
    .sys_rst_n      (sys_rst_n),
    
    .uart_rxd       (uart_rxd),
    .uart_done      (uart_done),
    .uart_data      (uart_data),
    .recv_done      (uart_recv_done),
    .dataA          (dataA),    
    .dataB          (dataB),    
    .dataC          (dataC)  
    );
    
//串口發(fā)送模塊    
uart_send #(                          
    .CLK_FREQ       (CLK_FREQ),         //設置系統(tǒng)時鐘頻率
    .UART_BPS       (UART_BPS))         //設置串口發(fā)送波特率
u_uart_send(                 
    .sys_clk        (sys_clk),
    .sys_rst_n      (sys_rst_n),
    
    .cnt            (cnt),
    .uart_en        (uart_send_en),
    .uart_din       (uart_send_data),
    .uart_tx_busy   (uart_tx_busy),
    .uart_txd       (uart_txd)
    );

 //串口環(huán)回模塊    
uart_loop u_uart_loop(
    .sys_clk        (sys_clk),             
    .sys_rst_n      (sys_rst_n),           
   
    .uart_done      (uart_done),        //接收單字節(jié)數(shù)據(jù)接收一幀數(shù)據(jù)(30字節(jié)數(shù)據(jù))完成標志信號,4字節(jié)幀頭,3*8=24字節(jié)數(shù)據(jù),2字節(jié)幀尾
    .uart_data      (uart_data),        //接收的數(shù)據(jù)
    .tx_busy        (uart_tx_busy),     //發(fā)送忙狀態(tài)標志 
    
    .cnt            (cnt),     
    .send_en        (uart_send_en),     //發(fā)送使能信號
    .send_data      (uart_send_data)    //待發(fā)送數(shù)據(jù)
    );   

    
endmodule

分模塊代碼:文章來源地址http://www.zghlxwxcb.cn/news/detail-713571.html

`timescale 1ns / 1ps
module uart_recv(
    input			  sys_clk,                  //系統(tǒng)時鐘
    input             sys_rst_n,                //系統(tǒng)復位,低電平有效
    input             uart_rxd,                 //UART接收端口

	 output  reg [ 7:0] uart_data,	             //接收的數(shù)據(jù)
	 output  reg        uart_done,              //接收一字節(jié)數(shù)據(jù)完成標志
	 
	 output  reg        uart_get,               //單字節(jié)采樣點
	 
	 output  reg [7:0] pack_cnt,                //字節(jié)計數(shù)
	 output  reg       pack_ing, 	            //接收過程標志位
	 output  reg       pack_done,               //幀接收完成標志位
	 output  reg [7:0] pack_num,                //接收到的字節(jié)數(shù)
	 output  reg       recv_done,              //接收完一幀數(shù)據(jù)的接收和解碼
	 output  reg [63:0] dataA,                 //解碼后數(shù)據(jù),8*8=64bit
	 output  reg [63:0] dataB,                 //解碼后數(shù)據(jù),8*8=64bit
     output  reg [63:0] dataC                  //解碼后數(shù)據(jù),8*8=64bit
    );
    
localparam  DATA_NUM = 30;
integer j;

reg [7:0] pack_data [DATA_NUM-1:0];           //接收的數(shù)據(jù)
//parameter define
parameter  CLK_FREQ = 50_000_000;                 //系統(tǒng)時鐘頻率
parameter  UART_BPS = 115200;                     //串口波特率
localparam BPS_CNT  = CLK_FREQ/UART_BPS;        //為得到指定波特率
 
//localparam  TimeOut = BPS_CNT*DATA_NUM*10*2;//超時時間

//起始信號下降沿捕捉
wire       start_flag;
reg        uart_rxd_d0;
reg        uart_rxd_d1;

reg [15:0] clk_cnt;                             //系統(tǒng)時鐘計數(shù)器
reg [ 3:0] rx_cnt;                              //接收數(shù)據(jù)計數(shù)器
reg        rx_flag;                             //接收過程標志信號
reg [ 7:0] rxdata;                              //接收數(shù)據(jù)寄存器

//接收信號完成標志位上升沿
wire  rxdone_flag;
reg   uart_done_d0;
reg   uart_done_d1;
//包數(shù)據(jù)接收完成
wire  packdone_flag;
reg   pack_done_d0;
reg   pack_done_d1;

//*****************************************************
//**                    main code
//*****************************************************
//捕獲接收端口下降沿(起始位),得到一個時鐘周期的脈沖信號
assign  start_flag = uart_rxd_d1 & (~uart_rxd_d0);    
//對UART接收端口的數(shù)據(jù)延遲兩個時鐘周期
always @(posedge sys_clk or negedge sys_rst_n) begin 
    if (!sys_rst_n) begin 
        uart_rxd_d0 <= 1'b0;
        uart_rxd_d1 <= 1'b0;          
    end
    else begin
        uart_rxd_d0  <= uart_rxd;                   
        uart_rxd_d1  <= uart_rxd_d0;
    end   
end
//當脈沖信號start_flag到達時,進入接收過程           
always @(posedge sys_clk or negedge sys_rst_n) begin         
    if (!sys_rst_n)                                  
        rx_flag <= 1'b0;
    else begin
        if(start_flag)                          //檢測到起始位
            rx_flag <= 1'b1;                    //進入接收過程,標志位rx_flag拉高
        else if((rx_cnt == 4'd9)&&(clk_cnt == BPS_CNT/2))
            rx_flag <= 1'b0;                    //計數(shù)到停止位中間時,停止接收過程
        else
            rx_flag <= rx_flag;
    end
end
//進入接收過程后,啟動系統(tǒng)時鐘計數(shù)器與接收數(shù)據(jù)計數(shù)器
always @(posedge sys_clk or negedge sys_rst_n) begin         
    if (!sys_rst_n) begin                             
        clk_cnt <= 16'd0;                                  
        rx_cnt  <= 4'd0;
    end                                                      
    else if ( rx_flag ) begin                   //處于接收過程
            if (clk_cnt < BPS_CNT - 1) begin
                clk_cnt <= clk_cnt + 1'b1;
                rx_cnt  <= rx_cnt;
            end
            else begin
                clk_cnt <= 16'd0;               //對系統(tǒng)時鐘計數(shù)達一個波特率周期后清零
                rx_cnt  <= rx_cnt + 1'b1;       //此時接收數(shù)據(jù)計數(shù)器加1
            end
        end
        else begin                              //接收過程結束,計數(shù)器清零
            clk_cnt <= 16'd0;
            rx_cnt  <= 4'd0;
        end
end
//根據(jù)接收數(shù)據(jù)計數(shù)器來寄存uart接收端口數(shù)據(jù)
always @(posedge sys_clk or negedge sys_rst_n) begin 
    if (!sys_rst_n)  begin
        rxdata <= 8'd0;     
		  uart_get<=1'b0;		
	 end  
    else if(rx_flag)                            //系統(tǒng)處于接收過程
        if (clk_cnt == BPS_CNT/2) begin         //判斷系統(tǒng)時鐘計數(shù)器計數(shù)到數(shù)據(jù)位中間
            case ( rx_cnt )
             4'd1 : rxdata[0] <= uart_rxd_d1;   //寄存數(shù)據(jù)位最低位
             4'd2 : rxdata[1] <= uart_rxd_d1;
             4'd3 : rxdata[2] <= uart_rxd_d1;
             4'd4 : rxdata[3] <= uart_rxd_d1;
             4'd5 : rxdata[4] <= uart_rxd_d1;
             4'd6 : rxdata[5] <= uart_rxd_d1;
             4'd7 : rxdata[6] <= uart_rxd_d1;
             4'd8 : rxdata[7] <= uart_rxd_d1;   //寄存數(shù)據(jù)位最高位
             default:;                                    
            endcase
				uart_get<=1'b1;	
        end
        else  begin
            rxdata <= rxdata;
				uart_get<=1'b0;	
		  end
    else begin
        rxdata <= 8'd0;
		  uart_get<=1'b0;	
	 end
end


//數(shù)據(jù)接收完畢后給出標志信號并寄存輸出接收到的數(shù)據(jù)
always @(posedge sys_clk or negedge sys_rst_n) begin        
    if (!sys_rst_n) begin
        uart_data <= 8'd0;                               
        uart_done <= 1'b0;
    end
    else if(rx_cnt == 4'd9) begin               //接收數(shù)據(jù)計數(shù)器計數(shù)到停止位時           
        uart_data <= rxdata;                    //寄存輸出接收到的數(shù)據(jù)
        uart_done <= 1'b1;                      //并將接收完成標志位拉高
    end
    else begin
        uart_data <= 8'd0;                                   
        uart_done <= 1'b0; 
    end    
end

//---單字節(jié)接收程序,uart_done接收完成標志位會持續(xù)半個波特率周期,捕捉上升沿可以計數(shù),高電平狀態(tài),接收數(shù)據(jù)有效
//==============================================接收多個字節(jié),添加的模塊====================================================//

//捕獲接收完成標志位的上升沿,得到一個時鐘周期的脈沖信號
assign  rxdone_flag = uart_done_d0 & (~uart_done_d1);    
//對UART完成標志的數(shù)據(jù)延遲兩個時鐘周期
always @(posedge sys_clk or negedge sys_rst_n) begin 
    if (!sys_rst_n) begin 
        uart_done_d0 <= 1'b0;
        uart_done_d1 <= 1'b0;          
    end
    else begin
        uart_done_d0  <= uart_done;                   
        uart_done_d1  <= uart_done_d0;
    end   
end

//接收到的數(shù)據(jù)存入數(shù)組中,并計數(shù)
always @(posedge sys_clk or negedge sys_rst_n) begin      //接收到數(shù)據(jù)  
    if (!sys_rst_n) begin                             
		  pack_cnt <=8'd0;
		  pack_num <=8'd0;
		  pack_done<=1'b0; 
		  pack_ing <=1'b0;
		  for (j=0;j<DATA_NUM;j=j+1) 
		    pack_data[j] <= 8'd0;		 
    end
	 else if(rxdone_flag) begin //接收完成標志位的上升沿,延遲了兩個時鐘周期
		 if (pack_cnt < DATA_NUM-1) begin       //處于接收過程中
				 for (j=0;j<DATA_NUM;j=j+1) begin
				     if(j==pack_cnt)
					    pack_data[pack_cnt] <= uart_data;//寄存輸出接收到的數(shù)據(jù)
					  else
					    pack_data[j] <= pack_data[j];	
				 end
				 pack_cnt  <= pack_cnt + 1'b1; 
             pack_num <= 8'd0;	
		       pack_done<=1'b0; 
		       pack_ing <=1'b1;		 
		 end
		 else begin //接收完成---最后一個字節(jié)的接收
				 for (j=0;j<DATA_NUM;j=j+1) begin
				     if(j==pack_cnt)
					  pack_data[pack_cnt] <= uart_data;//寄存輸出接收到的數(shù)據(jù)
					  else
					  pack_data[j] <= pack_data[j];	
				 end
				 pack_num <= pack_cnt + 1'b1; //加上最后一個字節(jié)
			     pack_cnt <= 8'd0;               //此時接收數(shù)據(jù)計數(shù)器歸零,只有接收完成時才清零
				 pack_done<= 1'b1;      			 //輸出幀接收完成標志位,只存在一個周期
				 pack_ing <= 1'b0;
		 end  
	 end
	 else begin
		  pack_cnt <=pack_cnt;
		  pack_ing <=pack_ing;//保持
		  pack_num <=pack_num;
		  pack_done<=1'b0;  
		  for (j=0;j<DATA_NUM;j=j+1) 
		    pack_data[j] <= pack_data[j];	
	 end
end


//------------解碼-------------------------//
//捕獲接收完成標志位的上升沿,得到一個時鐘周期的脈沖信號
assign  packdone_flag = pack_done_d0 & (~pack_done_d1);    
//對UART完成標志的數(shù)據(jù)延遲兩個時鐘周期
always @(posedge sys_clk or negedge sys_rst_n) begin 
    if (!sys_rst_n) begin 
        pack_done_d0 <= 1'b0;
        pack_done_d1 <= 1'b0;          
    end
    else begin
        pack_done_d0  <= pack_done;                   
        pack_done_d1  <= pack_done_d0;
    end   
end

always @(posedge sys_clk or negedge sys_rst_n) begin         
    if (!sys_rst_n) begin                             
       dataA <= 8'd0; 
		 dataB <= 16'd0;
		 dataC <=16'd0;
		 recv_done <=1'b0;
    end  
	 else if(packdone_flag) begin //數(shù)據(jù)接收完成,進行解碼
		 if(pack_num==DATA_NUM && pack_data[0]==8'haa && pack_data[1]==8'hff && pack_data[2]==8'h03 && pack_data[3]==8'h00 && pack_data[28]==8'h55 && pack_data[29]==8'hcc ) begin  //判斷數(shù)據(jù)正誤
			 dataA <= {pack_data[4],pack_data[5],pack_data[6],pack_data[7],pack_data[8],pack_data[9],pack_data[10],pack_data[11]};
			 dataB <= {pack_data[12],pack_data[13],pack_data[14],pack_data[15],pack_data[16],pack_data[17],pack_data[18],pack_data[19]};
			 dataC <= {pack_data[20],pack_data[21],pack_data[22],pack_data[23],pack_data[24],pack_data[25],pack_data[26],pack_data[27]};
			 recv_done <=1'b1;
		 end  
		 else begin //數(shù)據(jù)錯誤
			 dataA <= 64'd0;
			 dataB <= 64'd0;
			 dataC <= 64'd0;
			 recv_done <=1'b0;
		 end
	 end
	 else begin //數(shù)據(jù)保持到下一個周期,標志位保持一個周期
		 dataA <= dataA;
		 dataB <= dataB;
		 dataC <= dataC;
		 recv_done <=1'b0;
	 end	 
end


endmodule	
`timescale 1ns / 1ps
module uart_send(
    input	      sys_clk,                  //系統(tǒng)時鐘
    input         sys_rst_n,                //系統(tǒng)復位,低電平有效
    
    input  [7:0]  cnt,
    input         uart_en,                  //發(fā)送使能信號
    input  [7:0]  uart_din,                 //待發(fā)送數(shù)據(jù)
    output        uart_tx_busy,             //發(fā)送忙狀態(tài)標志      
    output  reg   uart_txd                  //UART發(fā)送端口
    );
    
//parameter define
parameter  CLK_FREQ = 50000000;            //系統(tǒng)時鐘頻率
parameter  UART_BPS = 115200;                //串口波特率
localparam  BPS_CNT  = CLK_FREQ/UART_BPS;   //為得到指定波特率,對系統(tǒng)時鐘計數(shù)BPS_CNT次

//reg define
reg        uart_en_d0; 
reg        uart_en_d1;  
reg [15:0] clk_cnt;                         //系統(tǒng)時鐘計數(shù)器
reg [ 3:0] tx_cnt;                          //發(fā)送數(shù)據(jù)計數(shù)器
reg        tx_flag;                         //發(fā)送過程標志信號
reg [ 7:0] tx_data;                         //寄存發(fā)送數(shù)據(jù)

//wire define
wire       en_flag;

//*****************************************************
//**                    main code
//*****************************************************
//在串口發(fā)送過程中給出忙狀態(tài)標志
assign uart_tx_busy = tx_flag;

//捕獲uart_en上升沿,得到一個時鐘周期的脈沖信號
assign en_flag = (~uart_en_d1) & uart_en_d0;

//對發(fā)送使能信號uart_en延遲兩個時鐘周期
always @(posedge sys_clk or negedge sys_rst_n) begin         
    if (!sys_rst_n) begin
        uart_en_d0 <= 1'b0;                                  
        uart_en_d1 <= 1'b0;
    end                                                      
    else begin                                               
        uart_en_d0 <= uart_en;                               
        uart_en_d1 <= uart_en_d0;                            
    end
end

//當脈沖信號en_flag到達時,寄存待發(fā)送的數(shù)據(jù),并進入發(fā)送過程          
always @(posedge sys_clk or negedge sys_rst_n) begin         
    if (!sys_rst_n) begin                                  
        tx_flag <= 1'b0;
        tx_data <= 8'd0;
    end 
    else if (en_flag && (cnt>=8'd2)) begin                 //檢測到發(fā)送使能上升沿                      
            tx_flag <= 1'b1;                //進入發(fā)送過程,標志位tx_flag拉高
            tx_data <= uart_din;            //寄存待發(fā)送的數(shù)據(jù)
        end
                                            //計數(shù)到停止位結束時,停止發(fā)送過程
        else if ((tx_cnt == 4'd9) && (clk_cnt == BPS_CNT -(BPS_CNT/16))) begin                                       
            tx_flag <= 1'b0;                //發(fā)送過程結束,標志位tx_flag拉低
            tx_data <= 8'd0;
        end
        else begin
            tx_flag <= tx_flag;
            tx_data <= tx_data;
        end 
end

//進入發(fā)送過程后,啟動系統(tǒng)時鐘計數(shù)器
always @(posedge sys_clk or negedge sys_rst_n) begin         
    if (!sys_rst_n)                             
        clk_cnt <= 16'd0;                                  
    else if (tx_flag) begin                 //處于發(fā)送過程
        if (clk_cnt < BPS_CNT - 1)
            clk_cnt <= clk_cnt + 1'b1;
        else
            clk_cnt <= 16'd0;               //對系統(tǒng)時鐘計數(shù)達一個波特率周期后清零
    end
    else                             
        clk_cnt <= 16'd0; 				    //發(fā)送過程結束
end

//進入發(fā)送過程后,啟動發(fā)送數(shù)據(jù)計數(shù)器
always @(posedge sys_clk or negedge sys_rst_n) begin         
    if (!sys_rst_n)                             
        tx_cnt <= 4'd0;
    else if (tx_flag) begin                 //處于發(fā)送過程
        if (clk_cnt == BPS_CNT - 1)			//對系統(tǒng)時鐘計數(shù)達一個波特率周期
            tx_cnt <= tx_cnt + 1'b1;		//此時發(fā)送數(shù)據(jù)計數(shù)器加1
        else
            tx_cnt <= tx_cnt;       
    end
    else                              
        tx_cnt  <= 4'd0;				    //發(fā)送過程結束
end

//根據(jù)發(fā)送數(shù)據(jù)計數(shù)器來給uart發(fā)送端口賦值
always @(posedge sys_clk or negedge sys_rst_n) begin        
    if (!sys_rst_n)  
        uart_txd <= 1'b1;        
    else if (tx_flag)
        case(tx_cnt)
            4'd0: uart_txd <= 1'b0;         //起始位 
            4'd1: uart_txd <= tx_data[0];   //數(shù)據(jù)位最低位
            4'd2: uart_txd <= tx_data[1];
            4'd3: uart_txd <= tx_data[2];
            4'd4: uart_txd <= tx_data[3];
            4'd5: uart_txd <= tx_data[4];
            4'd6: uart_txd <= tx_data[5];
            4'd7: uart_txd <= tx_data[6];
            4'd8: uart_txd <= tx_data[7];   //數(shù)據(jù)位最高位
            4'd9: uart_txd <= 1'b1;         //停止位
            default: ;
        endcase
    else 
        uart_txd <= 1'b1;                   //空閑時發(fā)送端口為高電平
end

endmodule	          
`timescale 1ns / 1ps
module uart_loop(
    input	         sys_clk,                   //系統(tǒng)時鐘
    input            sys_rst_n,                 //系統(tǒng)復位,低電平有效
     
    input            uart_done,                 //接收一幀數(shù)據(jù)完成標志
    input      [7:0] uart_data,                 //接收的數(shù)據(jù)
     
    input            tx_busy,                   //發(fā)送忙狀態(tài)標志      
    output reg       send_en,                   //發(fā)送使能信號
    output reg[7:0]  cnt,
 //   output wire[7:0]  cnt0,
    output reg [7:0] send_data                  //待發(fā)送數(shù)據(jù)

    );

//reg define
reg uart_done_d0;
reg uart_done_d1;
reg tx_ready;

reg [4:0]state;
reg [7:0]cnt; 
reg [7:0]post_data;

//wire define
wire uart_done_flag;
//wire [7:0]cnt0; 

parameter IDLE=5'b00001,AASTATE=5'b00010,FFSTATE=5'b00100,STATE03=5'b01000,STATE00=5'b10000;
//*****************************************************
//**                    main code
//*****************************************************

//捕獲uart_done上升沿,得到一個時鐘周期的脈沖信號
assign uart_done_flag = (~uart_done_d1) & uart_done_d0;

//assign cnt0 = cnt;

//對發(fā)送使能信號uart_done延遲兩個時鐘周期
always @(posedge sys_clk or negedge sys_rst_n) begin         
    if (!sys_rst_n) begin
        uart_done_d0 <= 1'b0;                                  
        uart_done_d1 <= 1'b0;
    end                                                      
    else begin                                               
        uart_done_d0 <= uart_done;                               
        uart_done_d1 <= uart_done_d0;                            
    end
end

//判斷幀頭部分,不判斷幀尾,因為數(shù)據(jù)長度固定
always@(posedge sys_clk or negedge sys_rst_n)begin
    if(!sys_rst_n)begin  
    post_data<=8'd0;state<=IDLE;
    end
    else case(state)
    IDLE:begin 
    post_data<=8'b0;
    cnt<=8'd0;
    if(uart_done_flag)begin
        if(uart_data==8'hAA)state<=AASTATE;
        else state<=IDLE;
      end
    end
    AASTATE:if(uart_done_flag)begin
        if(uart_data==8'hFF)state<=FFSTATE;
        else state<=IDLE;
      end
    FFSTATE:if(uart_done_flag)begin
        if(uart_data==8'h03)state<=STATE03;
        else state<=IDLE;
      end
    STATE03:if(uart_done_flag)begin
        if(uart_data==8'h00)state<=STATE00;
        else state<=IDLE;
      end  
    STATE00:if(uart_done_flag)begin 
            post_data<=uart_data;
            cnt<=cnt+1'b1;//24個字節(jié)
            if(cnt==8'd25)begin //相對uart_data延遲了一個時鐘,所以cnt要多一位,防止丟失最后一個數(shù)據(jù)
            state<=IDLE;
            end
         end
    endcase 
end
//判斷接收完成信號,并在串口發(fā)送模塊空閑時給出發(fā)送使能信號
always @(posedge sys_clk or negedge sys_rst_n) begin 
    if (!sys_rst_n) begin
        tx_ready  <= 1'b0; 
        send_en   <= 1'b0;
        send_data <= 8'd0;
    end                                                      
    else begin                                               
        if(uart_done_flag)begin                 //檢測串口接收到數(shù)據(jù)
            tx_ready  <= 1'b1;                  //準備啟動發(fā)送過程
            send_en   <= 1'b0;
            send_data <= post_data;             //寄存串口接收的數(shù)據(jù),相對uart_data延遲了一個時鐘
        end
        else if(tx_ready && (~tx_busy)) begin   //檢測串口發(fā)送模塊空閑并且在有效數(shù)據(jù)區(qū)才發(fā)送數(shù)據(jù)使能信號
            tx_ready <= 1'b0;                   //準備過程結束
            send_en  <= 1'b1;                   //拉高發(fā)送使能信號
        end
    end
end

endmodule 

到了這里,關于基于FPGA的UART多字節(jié)環(huán)回實驗verilog代碼(含幀頭幀尾和解碼部分)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • FPGA(Verilog)實現(xiàn)uart傳輸協(xié)議傳輸數(shù)據(jù)(含仿真)

    FPGA(Verilog)實現(xiàn)uart傳輸協(xié)議傳輸數(shù)據(jù)(含仿真)

    目錄 實現(xiàn)功能: 1.接收uart串行數(shù)據(jù),輸出并行數(shù)據(jù)(1byte)。 2.輸入并行數(shù)據(jù)(1byte),輸出uart串行數(shù)據(jù)。 3.完成uart傳輸?shù)?次環(huán)回。 uart協(xié)議的1幀數(shù)據(jù)傳輸 模塊封裝-port設置 Verilog代碼實現(xiàn) 1.uart接收模塊:接收串行數(shù)據(jù),輸出并行數(shù)據(jù)和其有效標志。 仿真結果: 2.uart發(fā)送模塊:接收

    2024年04月16日
    瀏覽(21)
  • 基于FPGA的CAN通訊verilog代碼設計

    基于FPGA的CAN通訊verilog代碼設計

    FPAGA本篇文章參考github網(wǎng)站的開源項目can-FPGA-master編寫改進 在調(diào)試過程中,發(fā)現(xiàn)該項目無法在quartus pro13.0的環(huán)境下運行通過,代碼存在錯誤,并且對于EP4系列的芯片來說有太多的IO口,無法在燒錄,所以筆者對此進行了改進。 ?can_top模塊 can_tx傳輸數(shù)據(jù)模塊 can_rx接收數(shù)據(jù)模塊

    2024年02月08日
    瀏覽(23)
  • FPGA自學筆記--串口通信發(fā)送多字節(jié)數(shù)據(jù)(verilog版)

    FPGA自學筆記--串口通信發(fā)送多字節(jié)數(shù)據(jù)(verilog版)

    ????????關于uart協(xié)議實現(xiàn)這部分大家可以參考我上一篇的博客?!禙PGA自學筆記--串口通信實現(xiàn)(vivadoverilog版)》。在上一篇博客中,主要實現(xiàn)了將單字節(jié)的數(shù)據(jù),我們其實就是用上一篇博客的模塊來實現(xiàn)多字節(jié)數(shù)據(jù)的發(fā)送。 ????????在真實的數(shù)據(jù)傳輸過程中,我們不

    2023年04月17日
    瀏覽(23)
  • 基于FPGA的音樂噴泉控制Verilog代碼Quartus仿真

    基于FPGA的音樂噴泉控制Verilog代碼Quartus仿真

    名稱:基于FPGA的音樂噴泉控制Verilog代碼Quartus仿真(文末獲?。?軟件:Quartus 語言:Verilog 代碼功能: 基于FPGA的音樂噴泉控制 1、具有啟動控制按鍵,按下后開始 2、噴泉具有6個噴嘴,可以手動切換三種工作模式 3、輸入的音樂信號分為低音、中音、高音 4、將輸入的音轉換為

    2024年02月22日
    瀏覽(19)
  • 基于FPGA的MSK調(diào)制波形Verilog代碼Quartus仿真

    基于FPGA的MSK調(diào)制波形Verilog代碼Quartus仿真

    名稱:基于FPGA的MSK調(diào)制波形Verilog代碼Quartus仿真(文末獲?。?軟件:Quartus 語言:Verilog 代碼功能: 基于FPGA的MSK調(diào)制波形 1、輸入調(diào)制原始數(shù)據(jù),輸出MSK調(diào)制波形 2、包括差分編碼模塊,MSK調(diào)制模塊,DDS模塊,有符號乘法器模塊等 1. 工程文件 2. 程序文件 3. 程序編譯 4. RTL圖

    2024年02月20日
    瀏覽(22)
  • 基于FPGA的電風扇控制器verilog,視頻/代碼

    基于FPGA的電風扇控制器verilog,視頻/代碼

    名稱:基于FPGA的電風扇控制器verilog 軟件:QuartusII 語言:Verilog 代碼功能: 基于FPGA的電風扇控制器 ?運用 EDA SOPO實驗開發(fā)系統(tǒng)設計一個基于FPGA的電風扇定時開關控制器,能實現(xiàn)手動和自動模式之間的切換。要求:? (1)KI為電源開關由電源開關控制電風扇的開關,即當K1為高電平“

    2024年02月07日
    瀏覽(22)
  • FPGA協(xié)議篇:UART通信及Verilog最易懂實現(xiàn)方式/通用于任何工程/帶握手信號 ----UART_TX

    FPGA協(xié)議篇:UART通信及Verilog最易懂實現(xiàn)方式/通用于任何工程/帶握手信號 ----UART_TX

    ????????UART(Universal Asynchronous Receiver/Transmitter)是一種通用的 異步收發(fā)傳輸協(xié)議 ,用于在計算機系統(tǒng)和外部設備之間進行串行數(shù)據(jù)傳輸。UART 協(xié)議定義了數(shù)據(jù)的傳輸格式和通信規(guī)則,使得不同設備之間能夠進行可靠的數(shù)據(jù)交換。 首先先把設計代碼放到這里: UART_TX完整代

    2024年03月27日
    瀏覽(21)
  • FPGA與STM32之間的UART通信實驗

    FPGA與STM32之間的UART通信實驗

    目錄 1.UART串口介紹 2.實驗任務 3.FPGA代碼 4.STM32代碼 5.總結 ????????UART是一種采用異步串行方式的通用異步收發(fā)傳輸器,在發(fā)送數(shù)據(jù)時將并行數(shù)據(jù)轉換成串行數(shù)據(jù)來傳輸,在接收數(shù)據(jù)時將接收到的串行數(shù)據(jù)轉換成并行數(shù)據(jù)。 ????????UART串口通信需要兩根信號線來實現(xiàn),

    2024年02月13日
    瀏覽(32)
  • 基于FPGA的64bit算術乘法器設計Verilog代碼Quartus仿真

    基于FPGA的64bit算術乘法器設計Verilog代碼Quartus仿真

    名稱:基于FPGA的64bit算術乘法器設計Verilog代碼Quartus仿真(文末獲取) 軟件:Quartus 語言:Verilog 代碼功能: Verilog HDL設計64bits算術乘法器 基本功能 1.用 Veriloghdl設計實現(xiàn)64bit二進制整數(shù)乘法器,底層乘法器使用16*168*88*328*16小位寬乘法器來實現(xiàn)底層乘法器可以使用FPGA內(nèi)部P實現(xiàn)

    2024年02月19日
    瀏覽(23)
  • 基于EDA的電烤箱控制器設計Verilog代碼Quartus 新起點FPGA開發(fā)板

    基于EDA的電烤箱控制器設計Verilog代碼Quartus 新起點FPGA開發(fā)板

    名稱:基于EDA的電烤箱控制器設計Verilog代碼Quartus? 新起點FPGA開發(fā)板(文末獲?。?軟件:Quartus 語言:Verilog 代碼功能: 基于EDA的電烤箱控制器設計 主要研究內(nèi)容 設計一個電烤箱控制器電路,要求具有三檔加熱功能,分別表示燒烤加熱為低火、中火、高火。具有復位開關、啟動

    2024年02月01日
    瀏覽(32)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包