• FPGA-10:设计个简单的cpu(真的简单!)


    经过了之前的学习

    想必各位对verilog应该有了基本的基础

    那么,接下来,我们就来造cpu吧!

    我们将写一个简单的单周期cpu

    • 该cpu有一下特点:
      • 32位架构
      • 单周期执行
      • 简洁实用
      • 32位定长指令
      • 有手就行

    我称之为 “ant” 内核

    就跟蚂蚁一样,“功能弱小”,但也什么能干

    我也特地为该cpu编写了个汇编器

    包括使用python编写的bin转txt工具

    连接如下:

    click me

    下载该项目

    即可得到5个文件

    cpu.v: ant内核核心文件
    
    test.v : ant内核仿真文件
    
    ant-asm.exe: ant汇编器
    
    binTotxt.py:将bin文件转换成verilog可读取的储存器填充文件
    
    demo.ant:ant汇编例程
    

    下面是寄存器说明及指令集:

    寄存器:
    r0~r8 共16个32位寄存器,均可可读可写,
    r0~r14 通用寄存器
    r15 pc寄存器
    
    指令集:(总共14条)
    wh r0,num 写r0寄存器的高16位  {8{指令},4{寄存器id},16{常数},4{无意义}}
    wl r0,num 写r0寄存器的低16位  {8{指令},4{寄存器id},16{常数},4{无意义}}
    
    add r0,r1,r2 : r0 = r1 + r2 //整数加法 {8{指令},4{r0寄存器id},4{r1寄存器id},4{r2寄存器id},12{无意义}}
    sub r0,r1,r2 : r0 = r1 - r2 //整数减法 {8{指令},4{r0寄存器id},4{r1寄存器id},4{r2寄存器id},12{无意义}}
    or r0,r1,r2 : r0 = r1 | r2    {8{指令},4{r0寄存器id},4{r1寄存器id},4{r2寄存器id},12{无意义}}
    and r0,r1,r2 : r0 = r1 & r2   {8{指令},4{r0寄存器id},4{r1寄存器id},4{r2寄存器id},12{无意义}}
    not r0,r1 : r0 = ~r1          {8{指令},4{r0寄存器id},4{r1寄存器id},16{无意义}}
    sl r0,r1,r2 r0 = r1 << r2     {8{指令},4{r0寄存器id},4{r1寄存器id},4{r2寄存器id},12{无意义}}
    sr r0,r1,r2 : r0 = r1 >> r2   {8{指令},4{r0寄存器id},4{r1寄存器id},4{r2寄存器id},12{无意义}}
    mt r0,r1,r2 : r0 = r1 > r2 //比大小 返回0或1 {8{指令},4{r0寄存器id},4{r1寄存器id},16{无意义}}
    lt r0,r1,r2 : r0 = r1 < r2//同上 {8{指令},4{r0寄存器id},4{r1寄存器id},16{无意义}}
    
    rd r0,r1 : r1 = *r0//读内存   {8{指令},4{r0寄存器id},4{r1寄存器id},16{无意义}}
    wd r0,r1 : *r0 = r1//写内存   {8{指令},4{r0寄存器id},4{r1寄存器id},16{无意义}}
    
    if r0 :如果r0为非0,则跳过下一条指令
    

    虽然指令只有短短14条,但也几乎能够完成所有事了


    接下来我们来写个简单的1+2+3+...+100的程序

    c代码如下:

    int main() {
    	int all = 0;
    	int i = 1;
    	int j = 101;
    	int k = 0;
    
    l1:
    	k = i < j;
    	if (!k)
    		goto l2;
    	else
    		all = all + i;
    	i = i + 1;
    	goto l1;
    l2:
    
    	printf("%d", all);
    }
    

    c代码对应的汇编代码
    汇编代码如下:

    //0起始地址
    wl r0,0 //恒为0
    wh r0,0
    wl r1,1 //恒为1
    wh r1,0
    //累加
    wl r2,0
    wh r2,0
    //i
    wl r3,1 
    wh r3,0
    //101
    wl r4,101 
    wh r4,0
    //k
    wl r5,0
    wh r5,0
    //地址16
    wl r6,16
    wh r6,0
    //地址22
    wl r7,22
    wh r7,0
    //地址16:
    lt r5,r3,r4
    if r5//如果r3小于r4
    add r15,r7,r0
    add r2, r2, r3
    add r3,r3,r1
    add r15,r6,r0
    //地址22:
    wd r0,r2
    
    

    将该汇编代码保存进"demo.ant"文件中

    输入命令:

    ant-asm demo.ant
    
    

    即可得到

    out.bin可执行文件

    再执行binTotxt.py脚本(注意更改里面的路径)

    得到out.list填充文件

    仿真test.v文件,将out.list内容填充进rom

    运行

    仿真效果如下:

    0.png

    可以看到,正确的算出了5050这个值

    说明代码和ant内核是没有什么问题的

  • 相关阅读:
    SpringMvc的执行机制和环境搭建
    Flexbox,更优雅的布局
    Laravel框架 mysql 数据库 —— 基本使用
    在 Windows 上安装 Laravel 5.x
    javascript 中的借鸡生蛋
    由斐波那契数列所引发的性能优化
    成为一名优秀的Web前端开发者
    H5之contenteditable
    ionic 集锦
    vm10虚拟机安装Mac OS X10.10教程[转]
  • 原文地址:https://www.cnblogs.com/prprpr/p/14878152.html
Copyright © 2020-2023  润新知