Xilinx FPGA中使用PicoBlaze处理器软核

PicoBlaze8位微处理器,在Xilinx公司的VirtexSpartan-II系列以上FPGACoolRunner-II系列以上的CPLD器件设计中以IP核的方式提供,使用是免费的 (百度百科)。

常见的版本有KCPSM3KCPSM6。其中KCPSM支持7系列的Xilinx FPGA

PicoBlaze非常小,只有一个VHDL/Verilog文件,KCPSM6FPGA中只需要26块逻辑单元Slice,每个指令都可以再2个时钟周期内完成,在Spartan-6中可以达到105MHz时钟频率(-2速度等级),在Kintex-7-3速度等级)中能到达238MHz。它能提供两个寄存器Bank,每个Bank16个寄存器。

 

另外

 

很多时候我们用FPGAHDL语言很难实现某些功能,但是用软件方式就比较容易,但是我们又不希望花很多硬件资源去搭建一个嵌入式系统,比如基于MicroBlaze的系统。这样,我们就可以使用轻量级的PicoBlaze实现。

通常使用汇编语言写PicoBlaze程序,以KCPSM6为例,我们基于它的指令集可以很方便实现一些简单的程序,指令集如下:

 

Xilinx提供了相应的汇编器,可以生成带指令数据的ROMVHDL/Verilog代码,也可以生成HEX文件供动态加载到RAM

下面介绍开发流程,我们以一个简单的开关输入LED输出为例,之后我们会介绍简单的流水灯以及中断。

 

首先,我们去Xilinx官网下载所需的KCPSM6的相关文件以及辅助程序。下载地址:http://www.xilinx.com/ipcenter/processor_central/picoblaze/member/

本文基于ZedBoard进行试验,所以只需要下载PicoBlaze for UltraScale, 7-series, 6-series FPGAs 即可。下载后解压出来,会有很多实例,JTAG_Loader以及kcpsm6.exe汇编器等。

以下是汇编器的功能图:

 

一般情况下,我们的处理器系统如下所示:

 

Kcpsm6处理器核与rom相连,rom中装载我们的编译后的代码数据。这两个模块都是通过工具生成,不过我们的程序还是需要写汇编代码实现。

Kcpsm6外部信号很少,常用的就是in_portout_port,地址线和bram_enable以及instruction信号与rom相连,在不使用中断和休眠信号的情况下将interruptsleep拉低即可。Clk连接在FPGA外部输入的时钟引脚上,我们这里是Y9100MHz)。

本文使用Verilog语言实现硬件逻辑。

 

创建一个基于ZedBoardxc7z020-2clg484的工程。

建立一个顶层文件top.v,参照下载的文件夹中的Verilog目录中的kcpsm6_design_template.v,添加处理器核的例化

 

添加内部信号

 

另外,由于我们暂时没用到中断和休眠,将kcpsm6_sleepinterrupt拉低

 

我们再加入ROM的例化

 

将其中的<your program>改成后面汇编主程序文件名一样的名称。由于我们使用的Zedboard7系列的FPGA,故将上面的C_FAMILYV6改成7S

之后我们定义DIP开关作为输入管脚,并将内部In_port信号与其相连,定义输入管脚为LED,并将out_port信号与其相连。

 

 

现在,我们可以编写汇编程序了。这里先写一个最简单的程序,只是将输入端口01与输出端口01直接相连。

;8个LED
constant led_port,01
;8个DIP开关
constant dip_port,01
 
start:	    input s0,dip_port
output s0,led_port
jump start

 使用 对其进行编译,输入文件名回车,我们看到产生了4 个文件

 

 

其中生成的.v是我们现在需要的,也就是含指令的ROMVerilog代码,.hex文件是后面我们通过JTAG_LOADER动态修改程序时候需要的。

将产生的.v文件连同kcpsm6.v一起拷贝到ISE项目下,并编写UCF文件进行管脚和电平约束。

 

综合,生成比特流之后,将top.bitIMPACT下载到FPGA,就可以运行了。

 

下面我们换成流水灯的汇编程序。

;8个LED
constant led_port,01
load s0,01
output s0,led_port
start:  call delay1s
SLA s0
;output s0,led_port
jump start
delay1s: 
load s1,FF
call delay1
sub s1,01
output s1,led_port
jump c,delay1s
return
delay1:	  
load s2,FF
call delay2
sub s2,01
jump c,delay1
return;
delay2:	  
load s3,FF
call delay3
sub s3,01
jump c,delay2
return;
delay3:	  
load s4,04
sub s4,01
jump c,delay3
return;


 

这次我们编译后,使用JTAG_LOADER下载,不需要改变硬件配置。为了让JTAG_LOADER正常加载运行所需的dll,我们使用ISE Design Suite 64 Bit Command Prompt启动命令行,cdJTAG_LOADER路径

 

因为本文PCwin7 x64,故使用JTAG_Loader_Win7_64.exe,过程如下

 

 

对于中断的测试,我们首先需要开启硬件中的中断连接,我们添加一个input输入,UCF中连接到按键上,并将处理器核的interrupt信号连接到intinterrupt_ack信号是在进入中断服务程序前的响应信号,这里没有使用。由于picoblaze只提供一个中断输入,要实现多级中断,需要自己在FPGA中实现对应逻辑。

        

然后我们修改汇编程序,首先开启中断ENABLE INTERRUPT,然后在结尾加上中断服务程序,中断服务程序会自动关闭中断,跳出时候再恢复。

 

 


以下参考http://xilinx.eetrend.com/blog/2328

 

中断时序图

 

完整的中断程序,中断修改了s7寄存器的值,使得流水灯由两个灯变成一个灯:

;8个LED
constant led_port,01
 
ENABLE INTERRUPT
load s7,03
main:	load s0,s7
load sA,00
output s0,led_port
start:  load s1,0F
call delay1s
SLA s0
compare s0,00
jump z,main
output s0,led_port
jump start
delay1s: 
load s2,FF
call delay1
sub s1,01
COMPARE sA,s1
jump c,delay1s
return
delay1:	  
load s3,FF
call delay2
sub s2,01
COMPARE sA,s2
jump c,delay1
return
delay2:	  
load s4,04
call delay3
sub s3,01
COMPARE sA,s3
jump c,delay2
return
delay3:
sub s4,01
;COMPARE sA,s4
jump nc,delay3
return
 
;interrupt service routine
isr:	load s7,01
returni ENABLE
address 3FF
JUMP isr


相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页