开发环境
硬件平台:Smartfusion2
芯片型号:M2S010T-FG484
电脑系统: Windows 11
FPGA开发:Libero SoC v11.9
ARM开发:Keil4 uVision
实验内容
使用Libero SoC v11.9
从新建工程开始,完成以下功能:
按键
LED
UART
MSS与Fabric通信
DDR3的使用
LVDS IP核的添加
CAN接口的配置
介绍
简介
基于 Flash 架构的 SmartFusion2 是 Microsemi 的第四代 65nm 工艺的片上系统产品,是满足工业、军事、航空、通信和医疗领域所亟需的高安全性、高可靠性和极低功耗的 SoC
系统的唯一选择。
硬件资源
本实验硬件接口定义
晶振:50MHz 外部晶振
复位:R15(全局复位引脚)
KEY0:M1(Fabric模式)
KEY1:L2(Fabric模式)
LED0:M2(Fabric模式)
LED1:N1(Fabric模式)
LED2:P2(Fabric模式)
UART0:RX T18 TX T19
UART0:RX K6 TX K7
DDR3: DDR引脚是专用引脚,软件配置后会自动分配。
CAN:CAN_D C3 CAN_R C1
实验步骤
新建工程
新建General_project
工程。
选择芯片型号
修改PLL电压,PLL电压与硬件电路有关。
创建MSS
由于需要使用到MSS,所以需要创建MSS。
配置MSS资源
双击MSS模块,进入MSS配置界面。
时钟
双击MSS_CCC进入时钟配置。
使用此方法配置,需要添加时钟源,此配置是用于管理时钟为 Microcontroller Subsystem (MSS) 提供合适的时钟信号。MSS CCC 可以接收外部输入时钟(如晶振或其他外部时钟源)并通过内部的 PLL (Phase-Locked Loop) 实现分频、倍频或相位调整。配置Cortex-M3 核心、APB 总线外设、DDR 控制器、系统外设(如 UART、SPI 等)的时钟。
基础时钟根据外部晶振设定,外部晶振使用的是50MHz。
Monitor FPGA Fabric PLL Lock (CLK BASE_PLL LOCK) 是 FPGA 时钟管理功能中一个重要的状态信号,主要用于指示 FPGA 内部 Phase-Locked Loop (PLL) 是否已经成功锁定输入时钟信号并输出稳定的时钟。锁定之前,PLL 输出时钟可能是不稳定的,无法保证精度。
高电平 (1):PLL 已锁定,输出时钟稳定且可用。
低电平 (0):PLL 未锁定,输出时钟可能不稳定或无效。
Cortex-M3的时钟使用100MHz。
DDR时钟使用300MHz。
复位
双击RESET Controller
,进入复位信号配置。
Enable FPGA Fabric to MSS Reset (MSS_RESET_N_F2M)
FPGA Fabric 向 MSS 发送复位信号。对整个 MSS 系统进行重置。
Enable FPGA Fabric to M3 Reset (M3_RESET_N)
FPGA Fabric 向 MSS 内部的 Cortex-M3 核心 单独发送复位信号。仅对 MSS 的 Cortex-M3 核心生效,而不影响 MSS 的外设模块(如 UART、SPI)。
Enable MSS to FPGA Fabric Reset (MSS_RESET_N_M2F)
MSS(Cortex-M3 或其外设模块)向 FPGA Fabric 发送复位信号。
GPIO配置
开启GPIO外设
,双击GPIO
,进入GPIO配置。
开启两个GPIO引脚,分别对应KEY0和KEY0。按键设置为输入模式,LED设置位输出模式。
这两个引脚连接到FPGA的引脚上,但控制是由MSS完成。使用此方法在后面管脚约束时,可以自定义使用的管脚,若配置为IO口时,管脚编号则是固定的。
UART配置
开启MMUART_0M、MUART_0外设
,双击UART
,进入UART配置。
串口0和1,配置参数相同。
CAN接口配置
开启CAN外设
,双击CAN
,进入CAN配置。
DDR配置
开启DDR3外设
,双击DDR3
,进入DDR3配置。
导入配置文件,配置文件内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 ## PHY_16_DDR3_NO_ECC_BL8_INTER ddrc_dyn_soft_reset_CR 0x00 ; ddrc_dyn_refresh_1_CR 0x27DE ; ddrc_dyn_refresh_2_CR 0x030F ; ddrc_dyn_powerdown_CR 0x02 ; ddrc_dyn_debug_CR 0x00 ; ddrc_ecc_data_mask_CR 0x0000 ; ddrc_addr_map_col_1_CR 0x3333 ; ddrc_addr_map_col_3_CR 0x3300 ; ddrc_init_1_CR 0x0001 ; ddrc_cke_rstn_cycles_CR1 0x0100 ; ddrc_cke_rstn_cycles_CR2 0x0008 ; ddrc_init_emr2_CR 0x0000 ; ddrc_init_emr3_CR 0x0000 ; ddrc_dram_bank_act_timing_CR 0x1947; ddrc_odt_param_1_CR 0x0010 ; ddrc_odt_param_2_CR 0x0000 ; ddrc_debug_CR 0x3300 ; ddrc_mode_reg_rd_wr_CR 0x0000 ; ddrc_mode_reg_data_CR 0x0000 ; ddrc_pwr_save_2_CR 0x0000 ; ddrc_hpr_queue_param_CR1 0x80F8 ; ddrc_hpr_queue_param_CR2 0x0007 ; ddrc_lpr_queue_param_CR1 0x80F8 ; ddrc_lpr_queue_param_CR2 0x0007 ; ddrc_wr_queue_param_CR 0x0200 ; ddrc_dfi_min_ctrlupd_timing_CR 0x0003 ; ddrc_dfi_max_ctrlupd_timing_CR 0x0040 ; ddrc_dfi_wr_lvl_control_CR1 0x0000 ; ddrc_dfi_wr_lvl_control_CR2 0x0000 ; ddrc_dfi_rd_lvl_control_CR1 0x0000 ; ddrc_dfi_rd_lvl_control_CR2 0x0000 ; ddrc_dfi_ctrlupd_time_interval_CR 0x0309 ; ddrc_perf_param_3_CR 0x0000 ; ddrc_ecc_int_clr_reg 0x0000 ; ## Changed ones ddrc_mode_CR 0x0101 ; DDR3 + PHY-16 + ECC_DISABLE ddrc_addr_map_bank_CR 0x0999 ; PHY-16 ddrc_addr_map_col_2_CR 0xFFFF ; PHY-16 ddrc_addr_map_row_1_CR 0x8888 ; PHY-16 ddrc_addr_map_row_2_CR 0x08FF ; PHY-16 ddrc_init_emr_CR 0x0044 ; ddrc_dram_bank_timing_param_CR 0x01B0 ; ddrc_dram_rd_wr_latency_CR 0x0086 ; ddrc_dram_mr_timing_param_CR 0x005C ; ddrc_dram_ras_timing_CR 0x010F ; ddrc_dram_rd_wr_trnarnd_time_CR 0x0178 ; ddrc_zq_long_time_CR 0x0200 ; ddrc_zq_short_time_CR 0x0040 ; ddrc_zq_short_int_refresh_margin_CR1 0x0012 ; ddrc_zq_short_int_refresh_margin_CR2 0x0002 ; ddrc_dfi_rddata_en_CR 0x0005 ; ## Based on BL ddrc_init_mr_CR 0x0528 ; BL=8 + BT=Inter ddrc_dram_rd_wr_pre_CR 0x0235 ; BL=8 ddrc_dram_t_pd_CR 0x0033 ; PD Enable ddrc_pwr_save_1_CR 0x0506 ; PD Enable ddrc_perf_param_1_CR 0x4000 ; BL=8 ddrc_perf_param_2_CR 0x0400 ; Inter ddrc_axi_fabric_pri_id_CR 0x0000 ; ## PHY Registers Programming phy_loopback_test_CR 0x0000 ; PHY_LOOP_BACK != 1'b0 phy_ctrl_slave_ratio_CR 0x0080 ; phy_data_slice_in_use_CR 0x000F ; ECC != 1'b1 phy_dll_lock_diff_CR 0x000B ; phy_fifo_we_slave_ratio_CR1 0x0080 ; phy_fifo_we_slave_ratio_CR2 0x2004 ; phy_fifo_we_slave_ratio_CR3 0x0100 ; phy_fifo_we_slave_ratio_CR4 0x0008 ; phy_local_odt_CR 0x0001 ; phy_rd_dqs_slave_ratio_CR1 0x4050 ; phy_rd_dqs_slave_ratio_CR2 0x0501 ; phy_rd_dqs_slave_ratio_CR3 0x5014 ; phy_wr_data_slave_ratio_CR1 0x0050 ; phy_wr_data_slave_ratio_CR2 0x0501 ; phy_wr_data_slave_ratio_CR3 0x5010 ; phy_wr_rd_rl_CR 0x0043 ; phy_rdc_we_to_re_delay_CR 0x0003 ; phy_use_fixed_re_CR 0x0001 ; phy_use_rank0_delays_CR 0x0001 ; phy_dyn_config_CR 0x0000 ; phy_dq_offset_CR1 0x0000 ; phy_dq_offset_CR2 0x0000 ; phy_dyn_reset_CR 0x01 ; ddrc_dyn_soft_reset_alias_CR 0x01 ;
添加APB总线
APB总线是用于MSS与Fabric的通信。
设定Interface Type为APB3
,勾选Use Master Interface
(即 MSS 作为主机),其他设置默认。
保存
修改完参数后,保存后退出。
返回smart design
界面,MSS&出现感叹号,右键进行更新。
添加模块
在左侧菜单栏中,选择Catalog,在搜索框中搜索CCC、SYSREST。双击或拖动添加。
添加时钟源
时钟源使用外部输入的50M时钟,输出一个全局的时钟。
外部时钟源是不可以连接到其他模块上作为时钟输入的,必须经过此操作生成全局时钟(GL0)
添加复位源
DEVRST_N是物理引脚,在后面管脚约束时需要根据电路添加引脚。
同理,POWER_ON_RESET_N才是可以连接到模块的复位信号。
添加CoreAPB
修改CoreAPB参数。
添加自定义模块(MSS与Fabric通信功能)
选择设计流菜单,点击Create HDL
,或者从文件中新建HDL文件。
程序内容为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 module APBSlave_LED( // APB Slave Interface input [31:0] PADDR, input PSEL, input PENABLE, input PWRITE, output [31:0] PRDATA, input [31:0] PWDATA, output PREADY, // output PSLVERRS, // input clk_i, input rst_n_i, input key_i, output reg led0_o, output reg led1_o ); assign PREADY = 1'b1; //解析MSS的写操作 reg [31:0] DataFromMSS_r; reg [31:0] AddrFromMSS_r; always @ (posedge clk_i or negedge rst_n_i) begin if(!rst_n_i) begin DataFromMSS_r <= 32'd0; end else if(PWRITE & PSEL & PENABLE)begin // 写操作 AddrFromMSS_r <= PADDR; DataFromMSS_r <= PWDATA; end end //将MSS写入的数据发送到LED灯上显示 always @ (posedge clk_i or negedge rst_n_i) begin if(!rst_n_i) begin led0_o <= 0; led1_o <= 0; end else begin case(AddrFromMSS_r) 32'h3000_0000: led0_o <= DataFromMSS_r[0]; 32'h3000_0004: led1_o <= DataFromMSS_r[0]; default: begin led0_o <= led0_o; led1_o <= led1_o; end endcase end end //解析MSS的读操作 将KEY的状态返回至MSS reg [31:0] DataFromFabricToMSS_r; always @ (posedge clk_i or negedge rst_n_i) begin if(!rst_n_i) begin DataFromFabricToMSS_r <= 32'd0; end else if(!PWRITE & PSEL) begin case(PADDR) 32'h3000_0008: DataFromFabricToMSS_r <= {31'd0, key_i}; // 获取按键状态,按下为0 default: DataFromFabricToMSS_r <= DataFromFabricToMSS_r; endcase end else DataFromFabricToMSS_r <= DataFromFabricToMSS_r; end assign PRDATA = DataFromFabricToMSS_r; endmodule
添加的模块在Design Hierarchy
中
打包总线。在 Design Hierarchy 栏右键选择Create Core From HDL。选择 APB Slave 接口
将修改后的模块拖入设计中。
添加LVDS 模块。
在Catalog中搜索LVDS,将模块放入设计中。
将端口添加到顶层
为了引脚能够被管脚约束检测到。
画布布线
布线后,点击Generate Component,生成组件。
管脚约束
编译与下载
查看资源占用
导出Keil工程
参考文章
开发和环境的搭建、软件的使用、开发流程请查看下面文章。
Smartfusion2开发学习记录-开发环境搭建
软件其他功能使用,请查看下面文章。
Libero Soc v11.9使用(一)
Libero Soc联合Soft Console开发学习记录(二)
本文章,没有介绍逻辑分析仪等使用。如有需要查看下面连接。
Microsemi Libero SoC使用教程