马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
以r8051xc core为例简单介绍SOC/MCU架构设计, r8051xc IP 由以下公司提供, 由于下面展示的文档并没有公开,所以我只能展示目录,这是这个IP的设计文档,用户根据这个文档构建自己的MCU,当然是全英文的。
下面是r8051xc IP的源代码文件截图,这个也是不能公开的。
下面的文档是JTAG debugger 接口的文档,对应的仿真器是FS2 ,可自行百度。
JTAG debugger 接口有单独的代码,需要用户 integrating到IP。
MCU/SOC 架构设计需要做的: 1. 搭建初始的test bench ,先让这个MCU/SOC 跑起来,根据r8051xc 文档设置编译软件,用keil编译一个简单的代码(P0_1 置1),把编译出来的hex文件放入MCU/SOC 的code memory中,然后reset ,看代码是否能正常运行,这一步调试好了,接着就是第二步。有些IP自带简单test bench 和test case。 2. 根据项目需求,define 所有模块,编码并 integrating到IP 上,并编写c代码的test case,验证所有的模块功能。包括JTAG 接口,仿真时,代码可以直接读到code memory中($readmemh("code_load.txt",codemem);),但是还需要验证从JTAG接口下载到code Memory 中的功能。 3. 综合并下载到FPGA中,用仿真器进行联调,验证所有的功能。 B站有个MCU设计与验证的视频,讲了一部分。其中register file ,SRAM,ROM(现在已经很少用了),嵌入式flash(现在很多MCU(8051,stm32) 中都有,)这些都需要专门的厂家(TSMC…)来提供,一般都是memory compiler 来生成。
这里除了要用verilog写模块,写test bench ,还需要用tcl,shell 或 perl 写一些自动化脚本,用于验证。还需要会写嵌入式C语言,写一些简单 test case 来验证模块的功能。
下面是一个简单的提取hex 中的 code 的tcl脚本,提取到code_load.txt中 ,在test bench 中用
reg [ 7:0] codemem[0:262143];
$readmemh("code_load.txt",codemem);
写入到code memory中。
#!/usr/bin/tclsh
#HEX to txt (for 64 KB MEMORY)
#set fname {../keil_proj/all_test/all_test.hex}
#set fname {../keil_proj/dma_test4_1/dma_test4_1.hex}
set fname {../keil_proj/flash_test/flash_test.hex}
#set fname {../keil_proj/tc4eal_X2S_single/dma_buf_X2S.hex}
#set fname {../keil_proj/tc3eal_S2X_single/dma_serial0.hex}
#set fname {../keil_proj/spi/spi.hex}
#set fname {../core/keil_proj/CodeBanking/t_Bank_EX1/t.hex}
set f_code [open code_load.txt w]
set f_code_length [open code_addr.txt w]
set f1_code [open code_refec.txt w]
set f [open $fname r]
set tline ""
set code_line ""
set temp_code ""
set temp_code1 ""
set final_code ""
set code_length 0
set add 0
set code_end ":00000001FF"
while { [gets $f line ] >= 0 } {
set tline $line
#___________________________________________________
set len ""
append len 0x
set leng [string range $tline 1 2]
append len $leng
scan $len %x length
#puts $length
#___________________________________________________
#set addr ""
#append addr 0x
set addre [string range $tline 3 6]
puts $f_code_length $addre
#if{$code_length < $addre } {
#set code_length $addre
#}
#append addr $addre
#puts $addr
#scan $addr %x address
#puts $address
#__________________________________________________
set str_len [string length $tline]
set last_v [expr $str_len-3]
set code_line [string range $tline 9 $last_v]
set final_code ""
set str_eq [string equal $tline $code_end]
puts $str_eq
if {$str_eq == 0} {
set j 0
set i 0
append final_code @
append final_code $addre
append final_code " "
while { $i< $length} {
append final_code [string range $code_line $j [expr $j+1]]
append final_code " "
incr j 2
incr i 1
}
puts $f1_code $final_code
puts $f_code $final_code
}
}
close $f_code
close $f1_code
close $f
close $f_code_length
|