Cpu设计
这里有一个用Verilog HDL语言设计的计算机内核,可以运行简单的程序,我在研究生班教学中作为设计实例完成的。该设计已通过Quartus II软件环境的测试,并已下载到自制的开发实验板上运行。其中,内存是哈佛结构,直接利用Quartus II给出的内存元素组织而成。
程序
//基本输入时钟
//复位控制:reset_n,低电位有效。
//基本输出:o
//程序内存iram,16位,高5位为类指令代码,初始化为imem16.mif。
//数据存储器dram,16位,无数据文件初始化。
lpm存储器的地址信号在读写数据之前应该稳定在1拍。
//指令格式:高5位指令代码,11位地址码,16位立即数(分高低8位)。
模块测试
(
时钟,
重置_n,
哦,
//调试输出(可选):
opc,
奥马尔,
ojp,
oqw,
奥尔达,
oadd,
oout
);
输入时钟;
输入reset _ n;
output[15:0]o;
output[15:0]oqw;
output [10:0] opc,omar
输出[2:0]ojp;
输出olda、oadd、oout
电线dwren
wire[15:0]q _ w;
wire[15:0]q _ data;
reg [15:0] b,a,ir,da,oo,ddata
reg [10:0] pc,mar
reg[2:0]jp;//节拍
reg dwrit//写控制
//指令:
Reg lda,// fetch:从数据单元取数到da。
Add,// Add: da加到数据单元,结果放入da。
Out,// output:将数据单元的内容输出到输出寄存器。
Sdal,//低位8位立即数:将8位立即数扩展为16位并发送给da。
Sdah,//高8位立即数:将8位立即数作为高8位,与原da的低8位连接,形成16位,放入da中。
str//da发送数据存储单元:
//模拟信号输出:
赋值o = oo
分配opc = pc
赋值omar = mar
赋值ojp = jp
赋值oqw = q _ w;
赋值olda = lda
assign oadd = add
赋值oout = out
赋值dwren = dwrit
//指令存储器:
lpm_rom iram(。地址(个人电脑)。inclock(时钟)。q(q _ w));//程序存储器
def param iram . LPM _ width = 16;
def param iram . LPM _ width ad = 11;
defparam iram.lpm_outdata = "未注册";
def param iram . LPM _ in data = " REGISTERED ";
def param iram . LPM _ address _ control = " REGISTERED ";
def param iram . LPM _ file = " imem 16 . MIF ";//初始化文件并放置程序。
//数据存储:
lpm_ram_dq dram(。数据(ddata)。地址(mar)。我们(dwren)。inclock(时钟)。q(q _ data));def param dram . LPM _ width = 16;
def param dram . LPM _ width ad = 11;
defparam dram.lpm_outdata = "未注册";
def param dram . LPM _ in data = " REGISTERED ";
def param dram . LPM _ address _ control = " REGISTERED ";
always @(正边沿时钟或负边沿复位_n)
开始
如果(!reset_n)
开始
pc & lt= 0;
lda & lt= 0;
添加& lt= 0;
out & lt= 0;
sdal & lt= 0;
sdah & lt= 0;
str & lt= 0;
jp & lt=0;
结束
其他
开始
jp & lt= jp+1;
案例(jp)
0:开始
结束
1:开始
案例(q_w[15:11])
5 ' b 00001:LDA & lt;= 1;//lda:00001
5 ' b 00010:add & lt;= 1;//地址:00010
5 ' b 00011:out & lt;= 1;//out:00011
5 ' b 00100:sdal & lt;= 1;//低8位,用带符号的16位扩展
5 ' b 00101:sdah & lt;= 1;//高8位,与前面的低8位组合形成16位。
5 ' b 00110:str & lt;= 1;//da发送数据单元
结束案例
结束
2:开始
if (lda || add || out || str)
mar & lt= q _ w[10:0];
结束
3:PC & lt;= PC+1;
4:开始
中频(lda)
开始
da & lt= q _ data
jp & lt= 0;
lda & lt= 0;
结束
其他
如果(添加)
开始
b & lt= q _ data
a & lt= da
结束
其他
如果(出局)
开始
oo & lt= q _ data
jp & lt= 0;
out & lt= 0;
结束
其他
如果(sdal)
开始
da & lt= {{8{q_w[7]}},q _ w[7:0]};//扩展为16有符号数。
sdal & lt= 0;
结束
其他
if (sdah)
开始
da[15:0]& lt;= {q_w[7:0],da[7:0]};
sdah & lt= 0;
结束
其他
if(字符串)
开始
ddata & lt= da
dwrit & lt= 1;
结束
结束
5:开始
如果(添加)
开始
da & lt= a+b;
jp & lt= 0;
添加& lt= 0;
结束
其他
if(字符串)
开始
str & lt= 0;
dwrit & lt= 0;
结束
结束
结束案例
结束
结束
末端模块
///////////模拟或执行程序的示例/////////
//assembly//
// sdal 5 2005 //
// sdah 6 2806 //
// str 10 300a //
// sdal 3 2003 //
//添加10 100a //
// str 15 300f //
// out 15 180f //
//将编译后的16十六进制数写入imem16.mif //
//////16结果输出:0608/////////。