本文主要介绍汇编语言程序设计中跑马灯程序的设计要求,GPIO的概念和相关硬件知识,为之后分析汇编程序做准备。
1. 跑马灯的设计:
使用汇编语言实现跑马灯。
程序设计要求: 假设系统时钟50Mhz,状态机版本RISC-V CPU约每3个时钟周期执行一条指令。
设计要求:系统中有8个LED(汇编语言代码中使用寄存器x10),在risc-v cpu 的硬件连接中, 我们将 LED[7:0] 连接到 risc-v cpu GPIO外设的A组外设寄存器[7:0], 约每500ms右移1位,点亮对应的LED灯,当移到最后一个灯的时候(bit 0),再从最左端开始重新右移,要求每次只有一个LED灯为点亮状态。
2. 知识点回顾:
RISC-V 通用寄存器部分:CPU一共有32个通用寄存器,每个通用寄存器的宽为32位。
因为LED在开发板上采用共阳极方式设计,所以FPGA管脚为低电平时LED点亮。如下图原理图中所示。
图1. PRX100T开发板LED电路原理图
GPIO 的外设地址设定为0xF000_0000,其中0xF000_0000为IO的输入/输出寄存器,0xF000_0004为方向控制寄存器IO_dir[31:0];
输出:
当IO_dir[x](x=0~31)为0时,0xF000_0000对应的寄存器的值输出到IO端口,
输入:
当IO_dir[x]=1’b1时,CPU指令读取0xF000_0000时,得到的是IO端口外部的输入。
当IO_dir[x]=1’b0时,CPU指令读取0xF000_0000时,得到的是输出寄存器的值。
PC为32位宽寄存器,对应的最大寻址空间是4G。CPU地址分配可参考CPU address map文件。其中包括GPIO专用地址的相关介绍。
GPIO(General Purpose Input Output)通用输入输出管脚,可以作为输入管脚也可以作为输出管脚使用。
当方向寄存器为0时(IO_dir),地址0xF000_0000保存的32bit值就是GPIO管脚的输出值。
更改0xF000_0000的值等于更改了GPIO输出的值。该值每一位都对应一个gpio管脚的输出值。理论上一个地址可以控制32个gpio管脚,但是实际上在开发板上只能控制8个管脚,因为硬件上只给cpu留了8个管脚的资源,在该cpu的0xf000_0000地址上只有低8位的值是有用的。
注意:
IO_dir[x]中的x不是上文提到的x寄存器,而是index索引号。表示理论上可以有32个IO。
理论上在输出模式下我们依然可以读取一个gpio端口的值,但是因为是输出模式,读取的会是刚才输出的值。
FPGA GPIO的概念与结构:
图2.GPIO电路模型
上图为一个FPGA GPIO接口的电路模型。中间是一个tri-state三态门模型。此处为控制脚低电平有效,T为0时三态门有效导通,高电平或低电平随即从寄存器、触发器输出,GPIO为输出模式。当T为1时,输出端截止,IO是“Z”高阻状态。这样会阻断输出,但是可以读取输入。该CPU中IO位置的地址为0xF000_0000, T的地址为0xF000_0004,如上图所示。T就是上文中说明的方向控制寄存器。给T的地址相应位赋值1使gpio口输出,赋值0 gpio口作为输入。