手把手玩转Cortex-M3硬核系统
总线矩阵用参数化设计,想加挂新设备改个配置表就行,比搭积木还简单。工程编译后,可以在altera或者xilinx的fpga上运行并使用jlink盒子的swd模式读写指定地址。工程编译后,可以在altera或者xilinx的fpga上运行并使用jlink盒子的swd模式读写指定地址。swd的仿真模型,仿真时可以进行swd仿真读写指定地址或寄存器,非常方便。swd的仿真模型,仿真时可以进行swd仿真读
CortexM3的MCU最小系统,只有数字逻辑,可以仿真并在FPGA运行 [1]具体结构: CortexM3模型代码 AHB+APB总线结构 128K*2 SRAM(实现了包含bootloader) [2]这个工程环境的优势: 代码完整,包含RTL仿真、FPGA编译、firmware编译的各种脚本,可以一键式操作 fpga上可以通过swd下载firmware或者读写指定地址。 swd的仿真模型,仿真时可以进行swd仿真读写指定地址或寄存器,非常方便。 可以运行用户firmware,包括支持armgcc或者keil工程两种方式。 可以加挂用户自己的ip进行仿真调试。 除了M3、总线和fpga ip核外,整个工程都是。 工程编译后,可以在altera或者xilinx的fpga上运行并使用jlink盒子的swd模式读写指定地址。 适合有linux eda环境基础的mcu初学者,是很好的mcu硬件架构学习资料

这个基于Cortex-M3的MCU最小系统简直就是数字逻辑玩家的游乐场。整个架构用Verilog实现,既有工业级总线的规范感,又保持着开源项目的灵活度。咱们直接上硬菜——先看总线架构的关键代码:
// AHB总线接口定义
module ahb_lite_bus (
input HCLK,
input HRESETn,
input [31:0] HADDR,
input [1:0] HTRANS,
input HWRITE,
input [2:0] HSIZE,
input [31:0] HWDATA,
output [31:0] HRDATA,
output HREADY
);
// 总线矩阵实现略...
endmodule
这段代码藏着两个小心机:HSIZE参数支持8/16/32位混合访问,HREADY信号实现等待状态插入。总线矩阵用参数化设计,想加挂新设备改个配置表就行,比搭积木还简单。

CortexM3的MCU最小系统,只有数字逻辑,可以仿真并在FPGA运行 [1]具体结构: CortexM3模型代码 AHB+APB总线结构 128K*2 SRAM(实现了包含bootloader) [2]这个工程环境的优势: 代码完整,包含RTL仿真、FPGA编译、firmware编译的各种脚本,可以一键式操作 fpga上可以通过swd下载firmware或者读写指定地址。 swd的仿真模型,仿真时可以进行swd仿真读写指定地址或寄存器,非常方便。 可以运行用户firmware,包括支持armgcc或者keil工程两种方式。 可以加挂用户自己的ip进行仿真调试。 除了M3、总线和fpga ip核外,整个工程都是。 工程编译后,可以在altera或者xilinx的fpga上运行并使用jlink盒子的swd模式读写指定地址。 适合有linux eda环境基础的mcu初学者,是很好的mcu硬件架构学习资料

存储系统更是个狠角色,双端口SRAM的设计让bootloader和用户程序各玩各的:
sram_128kx32 boot_ram (
.clk_a (hclk),
.addr_a(boot_addr),
.dout_a(boot_data),
.clk_b (debug_clk),
.we_b (debug_wr),
.addr_b(debug_addr),
.din_b (debug_wdata),
.dout_b(debug_rdata)
);
左边接M3内核,右边留给调试接口,两边时钟域完全独立。这个设计让在线更新固件时系统还能继续跑,有点热插拔那味儿了。

工程环境才是真香现场。Makefile脚本三杀操作:
all: sim fpga flash
sim:
./run_sim.sh --test swd_rw
fpga:
vivado -mode batch -source build.tcl
flash:
openocd -f jlink.cfg -c "program user_fw.bin 0x08000000"
SWD仿真模型更是个宝藏,用Python都能调戏硬件:
from swd_model import DebugPort
dp = DebugPort()
dp.write_mem(0x20000000, b'\x01\x02\x03\x04')
data = dp.read_mem(0x20000000, 4)
print(f"读回数据:{bytes.hex(data)}")
想加自定义外设?在APB总线上挂个模块就能出道:
apb_regbank #(
.ADDR_MAP( 32'h40000000 ),
.REG_NUM ( 8 )
) my_ip (
.PCLK (pclk),
.PRESETn (presetn),
.PADDR (paddr),
.PWDATA (pwdata),
.PRDATA (prdata),
.PENABLE (penable)
);
FPGA实测环节,用J-Link Commander搞事情:
J-Link>SWD
J-Link>mem 0x20000000,4
20000000 = 01 02 03 04
整个项目就像乐高技术套装——既有规范的总线接口,又留足了魔改空间。建议从blinky例程开始,先让LED闪起来,再慢慢调戏存储映射,最后开发自己的外设。玩转这套系统,MCU底层那点事儿基本就门儿清了。




更多推荐
所有评论(0)