概论
SoC是在单个芯片上集成数字、模拟电路、CPU、DSP等各种模块,实现一个系统的功能,集成度高、可靠性好、成本低。本设计为一个基于OR1200的系统设计,各模块之间采用wishbone总线连接,所使用的主要模块有GPIO、on chip memory、PLL、定时器模块(PTC)、串口(uart16550)、外部中断模块。系统软件实现的功能为通过按键控制LED灯,通过中断,在中断服务函数中通过串口发送数据,通过定时器产生一个PWM波,来调节LED灯的亮度。
系统源码 qq 3270516346
文章目录
一、系统总体功能概述
1、系统硬件模块
① OR1200处理器
② wishbone总线
③ 定时/计数器模块(PTC)
④ 串口模块(UART)
⑤ 锁相环模块(PLL)
⑥ GPIO接口模块
⑦ 片上存储器模块(on chip memory)
2、各模块连接
3、系统总体功能
将GPIO配置为双向端口,将GPIO的低8位定义为输出,并连接到LED灯上,高八位定义为输入并连接到按键上,通过按键控制LED的亮灭。启用外部中断,当输入为上升沿时触发中断,在中断服务函数中,通过串口向终端发送数据。启用定时器,使用定时器产生PWM波,将定时器PWM的输出连接到LED上,控制LED的亮度。通过PLL模块来调节系统时钟频率为25MHz。
二、最小系统模块设计
1、OR1200
1、OR1200是OR1000的一种实现,源于OpenRISC项目,免费开源。
2、OR1200采用数据和指令分离的哈佛体系结构,为32位RISC处理器,所以OR1200占用两个主端口,rim和rdm端口,分别为指令和数据总线。
3、OR1200支持中断、电源管理灯多种功能
2、wishbone
1、wishbone总线是Silicore公司推出的片上总线标准,被opencore组织采用并维护。
2、wishbone支持8个主设备和16个从设备,内置仲裁器,允许多个主从设备进行通信
3、存储器
1、可以使用寄存器来实现存储器,也可以使用FPGA嵌入式存储块来实现
2、存储器生成以后,要采用wishbone总线进行封装,使其符合wishbone总线标准
三、各功能模块软硬件设计
1、GPIO
1、模块主要特征:
①用户可以从1到32之间选择通用IO信号的个数,更多信号可以采用多个GPIOP核并用。
②包含三态使能端或开漏使能端(需要三态或漏级开路IO单元)。
③设为输入的通用O信号可对CPU产生中断请求。
④设为输入的通用I/O信号能记录在系统时钟的上升沿或外部时钟的用户编程边沿。
2、GPIO模块主要由WISHBONE主机接口、GPIO寄存器、辅助输入输出端口、外部单元接口组成。GPIO核结构如下所示:
3、GPIO模块接口采用wishbone接口,在本设计中GPIO连接到wishbone总线的从接口14上,基地址定义为“GPIO_BASE 0xE0000000”。
4、GPIO的寄存器定义如下:
按照如上的定义定义寄存器的地址:
#define GPIO_BASE 0xE0000000
#define RGPIO_IN (GPIO_BASE + 0x0)
#define RGPIO_OUT (GPIO_BASE + 0x4)
#define RGPIO_OE (GPIO_BASE + 0x8)
#define RGPIO_INTE (GPIO_BASE + 0xc)
#define RGPIO_PTRIG (GPIO_BASE + 0x10)
#define RGPIO_AUX (GPIO_BASE + 0x14)
#define RGPIO_CTRL (GPIO_BASE + 0x18)
#define RGPIO_INTS (GPIO_BASE + 0x1c)
#define RGPIO_ECLK (GPIO_BASE + 0x20)
#define RGPIO_NEC (GPIO_BASE + 0x24)
5、在初始化GPIO时,设置高8位为输入,低8位为输出,开启外部中断,开启GPIO高8位输入的中断,并设置为上升沿触发中断。相应的GPIO初始化程序为:
void gpio_int()
{
REG32 (RGPIO_OE) = 0xff000000;
// gpio[31 :24] in gpio[23:0] out;
//中断设置
REG32( RGPIO_PTRIG)=0xff000000; //上升沿触发
REG32(RGPIO_INTS )=0x00000000; //清楚中断请求
REG32(RGPIO_INTE )=0xff000000; //开启外部中断
REG32 ( RGPIO_CTRL )=0x01; //开启总中断
6、将GPIO配置为双向端口,OE为输入输出控制端。将GPIO端口定义为“inout”类型,相应的模块结构如下:
对于每一位都可以单独设置为输入输出,相应的HDL描述为:
module set(
input oe,
input gpio_out,
output reg gpio_in,
inout gpio,
input clk
);
reg gpio_reg;
assign gpio=(oe==1'b1)?gpio_out:1'bz;
always @(posedge clk)
begin
if(oe)
gpio_reg<=gpio_out;
else
gpio_in<=gpio;
end
endmodule
2、UART
、UART为异步串行接口,数据在单条传输线上一位一位的传输,节省通信总线,码率低,本设计采用opencore上开源的UART 16550 IP模块。
2、在UART16550模块中,我们约定数据为8个数据位、1个停止位、无效验位,波特率设置位115200.
3、UART控制器表示如下:
UART接口控制器设计中只支持TXD和RXD两个信号。
4、设置串行通信的波特率为115200,波特率设置方式为“(输入时钟速度)/(除数锁存值)= 16 x 通信
波特率“。
5、在设计时我们通常只使用“void uart_putc(char c)”函数来发送数据,使用“void uart_init(void)”函数来初始化。
3、定时器、看门狗和PWM(PTC)
1、PTC的主要功能为:
①32位计时、计数功能;
②次或连续计时、计数;
③可编程PWM模式;
④系统时钟核外部时钟两种选择;HI/LO参考和捕获寄存器;
⑤PWM输出三态控制;
⑥PWM计时器/计数器计时中断;
⑦WISHBONE 接口兼容。
2、PTC模块的结构如下:
PTC通过WISHBONE接口连接到系统并与系统通信,PTC有4个与外部连接的端口。ptc_ecgt为当使用外部输入时钟时的时钟输入端;ptc_capt为使用捕获输入模式模式时,当输入下降沿或上升沿时,捕获当前的计数值;ptc_pwm为使用输出比较模式时,pwm波输出接口。
3、PTC的寄存器定义为:
PTC共有4个寄存器,我们将PTC连接到WISHBONE从模块的15端口,对于寄存器的定义为:
#define PTC_BASE 0xF0000000
#define RPTC_CNTR (PTC_BASE +0x00)
#define RPTC_HRC (PTC_BASE +0x04)
#define RPTC_LRC (PTC_BASE +0x08)
#define RPTC_CTRL (PTC_BASE +0x0C)
RPTC_CTRL为控制寄存器,其每一位都有相应的作用,将控制寄存器中的每一位单独定义:
#define en_set REG32(RPTC_CTRL)|=0x0001
#define en_reset REG32(RPTC_CTRL)&=0x0fffe
#define eclk_set REG32(RPTC_CTRL)|=0x0002
#define eclk_reset REG32(RPTC_CTRL)&=0x0fffd
#define nec_set REG32(RPTC_CTRL)|=0x0004
#define nec_reset REG32(RPTC_CTRL)&=0x0fffb
#define oe_set REG32(RPTC_CTRL)|=0x00008
#define oe_reset REG32(RPTC_CTRL)&=0x0fff77
4、我们使用PTC模块来产生pwm波形,在初始化时,首先使能PTC模块,然后使能pwm输出功能,配置定时器为自动循环计数方式,然后设置HRC和LRC的值,以配置pwm的频率和占空比。
void pwm_init(int lrcm,int hrcm)
{
en_set;
oe_set;
single_reset;
lrc=lrcm;
hrc=hrcm;
}
在产生pwm波时,定时器计数到LRC的值时,在从0开始计数;当当前计数值小于HRC时pwm输出为低电平,当当前计数值大于HRC的值时,pwm输出高电平,所以LRC决定pwm的频率,HRC决定pwm的占空比。
4、锁相环设置(PLL)
1、锁相环能调节输入时钟的频率和相位,我们采用PLL模块将FPGA上50MHz的信号时钟变为25MHz。
2、
四、软件设计
1、中断设置
1、需要先使用“l.mtspr”配置特殊功能寄存器开处理器中断;中断服务函数使用“l.rfe”返回。开中断操作为:
l.mfspr r1,r0,0x0011
l.ori r3,r1,0x6
l.mtspr r0,r3,0x0011
2、外部中断对应的中断向量地址为0X800,当外部中断响应后,程序就会跳转到0x800地址处执行相应的程序。
3、在0x800处,跳转到相应的中断服务函数处,在中断服务函数中,要清楚中断标志位,即使“REG32(RGPIO_INTS )=0x00000000;”中断服务函数执行完毕后调用“l.rfe”指令恢复现场,接着执行相应的程序。
2、主程序设计
1、在主程序中,首先初始化串口、定时器和GPIO,配置定时器频率为1kHz,占空比为50%。
2、相应的C程序为:
int main (void)
{
uart_init();
uart_print_str("\nstart\n");
gpio_int();
pwm_init(4999,4440);
gpio_out=0x00fffff;
while(1)
{
out();
delay_ms(10);
}
}
3、中断服务函数设计
在中断服务函数中,首先通过串口打印相应的字符,然后在清楚中断,调用“l.rfe”指令进行中断返回。
void gpios(void)
{
uart_print_str("\nexit\n");
exit_clear();
}
void exit_clear()
{
REG32(RGPIO_INTS )=0x00000000;
re();
}
五、结果验证
1、仿真验证
通过Modelsim进行仿真,对系统施加一定的激励,观察输出的时序。
观察的gpio输出值和串口打印数据为:
观察的pwm的输出为:
可以看到有相应的pwm波生成。
2、FPGA系统验证
将所设计的系统下载到FPGA中进行验证
设计步骤为分析综合、映射、布局、布线、管脚分配,在FPGA上上的引脚分配为: