2020-10-03

秦韵 FPGA 转载或原创(三)

高云FPGA GW2AR-18

今天就高云的Uart Master IP 的使用写一篇介绍,希望对大家的使用有所帮助。
**1)新建工程,选择器件,如GW2AR-18 **
使用IP Generateor 选择uart Master IP ,波特率可选,默认为9600,然后点击ok,完成ip的编辑。
该部分为ip生成的顶层接口,由于该ip内部封装了sram,故有留出的sram写接口和sram读接口,也支持调制解调功能(Modem),这次不讨论该部分内容,主要来实现uart的收发功能。

UART_MASTER_Top (
	  I_CLK,
	  I_RESETN,
	  I_TX_EN,
	  I_WADDR,
	  I_WDATA,
	  I_RX_EN,
	  I_RADDR,
	  O_RDATA,
	  SIN,
	  RxRDYn,
	  SOUT,
	  TxRDYn,
)

** 2) 关于这部分引脚的定义,可以参考IPUG511-1.4.pdf。 用不到的这里就不作说明了(直接删掉了,也不做例化),主要解释一下需要用到的引脚,串口的收发引脚 SOUT, SIN ,RXRDYn,TXRDYn为接收和发送数据准备好信号,再加上sram的读写接口,基本上可以完成对该ip的操作,在操作该Master IP的同时,有两种方式,一种通过操作寄存器来实现uart在状态的获取,两外一种,可直接通过RXRDY和TXRDY两个信号来实现UART的收发。接下来,不多说了,直接上代码了。**

// ===========Oooo==========================================Oooo========
// =  Copyright (C) 2002-2020 WMPself.
// =                     All rights reserved.
// =====================================================================
//  
//  __      __      __
//  \ \    /  \    / /   
//   \ \  / /\ \  / /    
//    \ \/ /  \ \/ /     [File name   ] sram_ctrl.v
//     \ \/    \/ /      [Description ] UART Master Controller
//     /\/\    /\/\      [Timestamp   ] Thursday  Oct 2 19:53:30 2020
//    / /\ \  / /\ \     [version     ] 1.0.0
//   / /  \ \/ /  \ \    
//  /_/    \__/    \_\
// 
//
// ===========Oooo==========================================Oooo========
// Code Revision History :
// --------------------------------------------------------------------
// Ver: | Author |Mod. Date |Changes Made:
// V1.0 | wmp    |10/02/20  |Initial version
// ===========Oooo==========================================Oooo========
`define IF_DATA_WIDTH 8
module sram_ctrl(
    input                           clk,
    input                           rst_n,
    input                           start_cfg,
    input                           start_ier_en,
    input                           start_w,
    input                           start_r,
    output                          I_TX_EN,
    output [2:0]                    I_WADDR,
    output [`IF_DATA_WIDTH-1:0]     I_WDATA,  
    output                          I_RX_EN,  
    output [2:0]                    I_RADDR,
    input  [`IF_DATA_WIDTH-1:0]     O_RDATA, 
    input  [`IF_DATA_WIDTH-1:0]     i_wr_data,
    output reg                      error_flag,
    output                          receive_flag,
    output [`IF_DATA_WIDTH-1:0]     o_rd_data,
    output                          o_rd_data_valid
    
);
//*************************************************************************
localparam CFG_LCR_STR = 0;
localparam CFG_LCR_STP = 1;
localparam CFG_LCR_DON = 2;
localparam CFG_IER_STR = 3;
localparam CFG_IER_STP = 4;
localparam CFG_IER_DON = 5;

localparam WR_IDE = 4'h0;
localparam RW_LSR_IDE = 4'h1;
localparam RW_LSR_STR = 4'h2;
localparam RW_LSR_STP = 4'h3;
localparam RW_LSR_DON = 4'h4;

//localparam W_THR_IDE = 4'h4;
localparam W_THR_STR = 4'h5;
localparam W_THR_STP = 4'h6;
localparam W_THR_DON = 4'h7;

localparam R_LSR_IDE = 4'h8;
localparam R_LSR_STR = 4'h9;
localparam R_LSR_STP = 4'ha;
localparam R_LSR_DON = 4'hb;

localparam R_RBR_IDE = 4'hc;
localparam R_RBR_STR = 4'hd;
localparam R_RBR_STP = 4'he;
localparam R_RBR_DON = 4'hf;

localparam RD_IIR_IDE = 3'h0;
localparam RD_IIR_STR = 3'h1;
localparam RD_IIR_STP = 3'h2;
localparam RD_IIR_DON = 3'h3;
localparam RD_RBR_IDE = 3'h4;
localparam RD_RBR_STR = 3'h5;
localparam RD_RBR_STP = 3'h6;
localparam RD_RBR_DON = 3'h7;
///

reg         start_dl;
reg         cfg_tx_en;
reg [2:0]   cfg_waddr;
reg  [7:0]  cfg_wdata;
reg [2:0]   cfg_state;
reg         cfg_done;

reg         tx_en;
reg [2:0]   waddr;
reg  [7:0]  wdata;

reg         wr_rx_en;
reg [2:0]   wr_raddr;
reg  [7:0]  wr_rdata;
reg [7:0]   rdr_data;   //使能中断接收后,打开该定义
reg [3:0]   wr_state;
reg         wr_done;
reg [7:0]   wr_data_reg;

reg         rd_rx_en;
reg [2:0]   rd_raddr;
reg [2:0]   rd_state;
reg         rdr_valid;
///
assign receive_flag = wr_done;
assign I_TX_EN = cfg_done ? tx_en : cfg_tx_en;
assign I_WADDR = cfg_done ? waddr : cfg_waddr;
assign I_WDATA = cfg_done ? wdata : cfg_wdata;
assign I_RX_EN = cfg_done ? start_ier_en ? rd_rx_en : wr_rx_en : 1'b0;
assign I_RADDR = cfg_done ? start_ier_en ? rd_raddr : wr_raddr : 3'b000;
assign o_rd_data = start_ier_en ? ( rdr_valid ? rdr_data : 8'h0): 8'h0;
assign o_rd_data_valid = start_ier_en ? rdr_valid : 1'b0;
///
always @(posedge clk or negedge rst_n)
if(~rst_n)
   start_dl <= 1'b0;	 
else
   start_dl <= start_cfg; 

always @(posedge clk or negedge rst_n)
if(~rst_n) begin 
    cfg_state <= 0;
    cfg_tx_en <= 1'b0;
    cfg_waddr <= 3'b000;
    cfg_wdata <= 8'h00;
    cfg_done <= 1'b0;
end
else begin
    case(cfg_state)
        CFG_LCR_STR:
           if((start_dl == 1'b0) && (start_cfg == 1'b1))
            begin
                cfg_tx_en <= 1'b1;
                cfg_waddr <= 3'b011; //0x03,LCR
                cfg_wdata <= 8'h2B;
                cfg_state <= CFG_LCR_STP;
            end
           else
            begin
                cfg_tx_en <= 1'b0;
                cfg_state <= CFG_LCR_STR;	
            end   
        CFG_LCR_STP:
            begin 
                cfg_tx_en <= 1'b0;
                cfg_waddr <= 3'b000;
                cfg_wdata <= 8'h00;
                cfg_state <= CFG_LCR_DON;
            end
        CFG_LCR_DON:
            begin
                if(start_ier_en) begin 
                    cfg_state <= CFG_IER_STR;
                end
                else begin
                    cfg_done <= 1'b1;
                    cfg_state <= CFG_LCR_STR;
                end
            end
        CFG_IER_STR :
            begin
                cfg_tx_en <= 1'b1;
                cfg_waddr <= 3'b001; //0x01,IER
                cfg_wdata <= 8'h04;
                cfg_state <= CFG_IER_STP;
            end
        CFG_IER_STP : 
            begin 
                cfg_tx_en <= 1'b0;
                cfg_waddr <= 3'b000;
                cfg_wdata <= 8'h00;
                cfg_state <= CFG_IER_DON;
            end
        CFG_IER_DON : 
            begin
                cfg_state <= CFG_LCR_STR;	
                cfg_done <= 1'b1;
            end 
        default : cfg_state <= CFG_LCR_STR;
    endcase 
end


always @(posedge clk or negedge rst_n) 
if(~rst_n) begin 
    wr_state <= 0;
    tx_en <= 1'b0;
    waddr <= 3'b000;
    wdata <= 8'h00;
    wr_rx_en <= 1'b0;
    wr_raddr <= 3'b000;
    wr_rdata <= 8'h00;
    wr_done <= 1'b0;
    wr_data_reg <= 8'd0;
    error_flag <= 1'b0;
end
else begin
    case(wr_state)
        WR_IDE :
            begin 
                if(cfg_done & start_w) begin
                    wr_state <= RW_LSR_IDE;
                end
                else if(cfg_done & start_r) begin
                    wr_state <= R_LSR_IDE;
                end
            end 
        RW_LSR_IDE : 
            begin 
                wr_rx_en <= 1'b1;
                wr_raddr <= 3'b101; //0x05,LSR
                wr_state <= RW_LSR_STR;
            end  
        RW_LSR_STR :
            begin 
                wr_rx_en <= 1'b0;
                wr_state <= RW_LSR_STP;
            end
        RW_LSR_STP :
            begin 
                wr_rdata <= O_RDATA;
                wr_state <= RW_LSR_DON;
            end
        RW_LSR_DON : 
            begin 
                if(wr_rdata[6] == 1'b1) begin
                    wr_state <= W_THR_STR;							   
                end	
                else if(wr_rdata[5] == 1'b1)
                    wr_state <= W_THR_STR;	
                else begin
                    wr_state <= WR_IDE;							   
                end							   
            end  
        W_THR_STR :
            begin
                tx_en <= 1'b1;
                waddr <= 3'b000; //0x00,THR
                wdata <= i_wr_data;
                wr_data_reg <= i_wr_data;
                wr_state <= W_THR_STP;
            end
        W_THR_STP :
            begin 
                tx_en <= 1'b0;
                waddr <= 3'b000;
                wdata <= 8'h00;
                wr_state <= W_THR_DON;
            end
        W_THR_DON :
            begin 
                wr_state <= WR_IDE;
            end
        R_LSR_IDE : 
            begin 
                wr_rx_en <= 1'b1;
                wr_raddr <= 3'b101; //0x05,LSR
                wr_state <= R_LSR_STR;
            end  
        R_LSR_STR :
            begin 
                wr_rx_en <= 1'b0;
                wr_state <= R_LSR_STP;
            end
        R_LSR_STP :
            begin 
                wr_rdata <= O_RDATA;
                wr_state <= R_LSR_DON;
            end
        R_LSR_DON : 
            begin 
                if(wr_rdata[0] == 1'b1) begin
                    wr_state <= R_RBR_IDE;							   
                end								  
                else begin
                    wr_state <= WR_IDE;							   
                end							   
            end 
        R_RBR_IDE :
            begin 
                wr_rx_en <= 1'b1;
                wr_raddr <= 3'b000; //0x000,RBR
                wr_state <= R_RBR_STR;
            end  
        R_RBR_STR :
            begin 
                wr_rx_en <= 1'b0;
                wr_state <= R_RBR_STP;
            end
        R_RBR_STP :
            begin 
                wr_rdata <= O_RDATA;
                wr_state <= R_RBR_DON;
            end
        R_RBR_DON : 
            begin 
                if(wr_done == 1'b1)	begin						   
                    if(wr_rdata != wr_data_reg) begin
                        error_flag <= 1'b1;
                    end
                    wr_state <= WR_IDE;
                end
                else begin
                    error_flag <= 1'b0;	
                    wr_done <= 1'b1;
                    wr_state <= R_RBR_IDE;
                end
            end
        default : wr_state <= WR_IDE;
    endcase
end

//************************************************
// * define isr[2] == 1'b1 , the regisiter is enable
// **********************************************

always @(posedge clk or negedge rst_n) 
if(~rst_n) begin 
    rd_state <= 0;
    rd_rx_en <= 1'b0;
    rd_raddr <= 3'b000;
    rdr_data <= 8'h00;
    rdr_valid <= 1'b0;
end
else begin
    case(rd_state)
        RD_IIR_IDE : 
            begin 
                if(start_ier_en) begin
                    rd_rx_en <= 1'b1;
                    rd_raddr <= 3'b010; //0x05,LSR
                    rd_state <= RD_IIR_STR;
                end
            end  
        RD_IIR_STR :
            begin 
                rd_rx_en <= 1'b0;
                rd_state <= RD_IIR_STP;
            end
        RD_IIR_STP :
            begin 
                rdr_data <= O_RDATA;
                rd_state <= RD_IIR_DON;
            end
        RD_IIR_DON : 
            begin 
                if(rdr_data[2] == 1'b1) begin
                    rd_state <= RD_RBR_IDE;							   
                end								  
                else begin
                    rd_state <= RD_IIR_IDE;							   
                end							   
            end  
        RD_RBR_IDE : 
            begin 
                if(start_ier_en) begin
                    rd_rx_en <= 1'b1;
                    rd_raddr <= 3'b000; //0x05,LSR
                    rd_state <= RD_RBR_STR;
                end
            end 
        RD_RBR_STR :
            begin 
                rd_rx_en <= 1'b0;
                rd_state <= RD_RBR_STP;
            end
        RD_RBR_STP :
            begin 
                rdr_data <= O_RDATA;
                rdr_valid <= 1'b1;
                rd_state <= RD_RBR_DON;
            end
        RD_RBR_DON : 
            begin
                rdr_valid <= 1'b0;
                rd_state <= RD_IIR_IDE;
            end
        default : 
            begin 
                rd_state <= RD_IIR_IDE;
            end
    endcase
end

endmodule

** 3)直接将驱动层的代码贴上来,可以直接调用来实现ip的控制,该部分我留下了中断方式的接口,未进行验证,如果有兴趣可进行验证,用过查询的方式实现起来比较简单,如果有兴趣,可以在fpga中跑软核,arm-m1或者riscv都欧克, 将该ip封装成AMBA 总线,挂载在AHB或者APB总线接口上,对于这部分的代码,也不算太难,主要是对该部分封装成总线形式。暂时就不上代码了。**
顶层接口module

// ===========Oooo==========================================Oooo========
// =  Copyright (C) 2002-2020 WMPself.
// =                     All rights reserved.
// =====================================================================
//  
//  __      __      __
//  \ \    /  \    / /   
//   \ \  / /\ \  / /    
//    \ \/ /  \ \/ /     [File name   ] uart.v
//     \ \/    \/ /      [Description ] UART Master Controller
//     /\/\    /\/\      [Timestamp   ] Thursday  Oct 2 19:53:30 2020
//    / /\ \  / /\ \     [version     ] 1.0.0
//   / /  \ \/ /  \ \    
//  /_/    \__/    \_\
// 
//
// ===========Oooo==========================================Oooo========
// Code Revision History :
// --------------------------------------------------------------------
// Ver: | Author |Mod. Date |Changes Made:
// V1.0 | wmp    |10/02/20  |Initial version
// ===========Oooo==========================================Oooo========
module uart (
	input       clk, 		//默认50M
    input       rst_n,
	output      tx_o,
	input       rx_o,
    output      error_flag  //拉到led上显示一下,做个测试。
    //usr logic
    ......
    //
)

4)放一个仿真的结果波形吧,做个结束好了
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值