来自于OPENCORE的Verilog语言的embedded_risc软核 - SOC资料区 - SOC设计论坛 - 中国电子顶级开发网论坛(EETOP) 国内顶级电子论坛,最活跃的电子工程师交流社区
http://bbs.eetop.cn/thread-251706-1-1.html
简介
一个简单的risc soc设计。不过大框架都有。很适合初学者。
自己还没有eda工具环境,之后再说。eda仿真环境搭建成功,根据波形和电路看,会容易很多。shit,搞完环境,竟然需要xilinx的fifo和rom原型。
指令集(大多跟ALU模块相关)
指令名 | 描述 | 实现 |
---|---|---|
STP; | 跳转? | |
LDA; | load | |
STO; | ||
ADD; | ||
SUB; | ||
JMP; | ||
JGE; | ||
JNE; | ||
STP; | ||
SHR; | ||
SHL; | ||
AND; | ||
OR; | ||
XOR; | ||
COM; | ||
SWP; | ||
NOP; |
指令文件program.txt
即程序。汇编代码。
testbench过程描述
步骤:
1. 复位
2. 复位释放
3. memory初始化;memory读取指令program.txt;
4. 仿真结束。
- reset是高有效的;与一般设计不一样,要注意。
主要模块描述
SOC系统架构图
risc uProcessor0
PC programCounter
program counter,又叫instruction point。程序计数器、指令指针等。
指令地址,从memory里读取指令的地址。
源代码得到的信息。
- 指令是24位;
- 疑问的地方,功能并不是计数器。计数器功能在ALU模块里。
module PC ( // Input
clock,
reset,
PCInEn,//pc使能
PCDataIn,//来自ALU模块
// Output
PCDataOut//只有pc使能有效,才会读取指令,否则输出为24'h0
);
IR InstructionRegister
- 数据宽度32位;
module IR ( // Input
clock,
reset,
IRInEn,//使能
IRDataIn,//来自外部memory模块
// Output
OperandOut,//操作运算数,IRDataIn低24位,打一拍
OpCodeOut//指令,IRDataIn高8位,打一拍
);
ACC Accumulator
module ACC( // Input
clock,
reset,
ACCInEn,//使能
ACCDataIn,//来自ALU模块
// Output
ACCNeg,//ACCDataIn[31]为1,则ACCNeg有效
ACCZero,//ACCDataIn[31:0]全零的标志flag
ACCDataOut//ACCDataIn[31:0]打一拍
);
ALU ALU
- 根据OpCode(指令码,就是指令功能。指令集)和CurrentState(判断取指、指令执行)。功能描述:
- 取指时,
if(OpCode !=STP) begin
ALUDataOut=ALUSrcB+1;
C=1;//指令地址加1
end
else begin
ALUDataOut=ALUSrcB;
C=0;
end
- 指令执行,即下述指令。
C=0;//指令地址不加
ALU操作名 | 描述 | 实现 |
---|---|---|
add; | 默认。 | ALUDataOut = ALUSrcA + ALUSrcB |
sub; | ALUDataOut = ALUSrcA - ALUSrcB | |
passB; | 结果等于源操作数B。跟nop一样,也许是没开发这个指令吧。 | ALUDataOut=ALUSrcB |
incB; | 应该是根据指令,判断下一个指令地址吧?!给PC用的?! | ALUDataOut = ALUSrcB + C |
shiftR; | 右移命令。针对的是源操作数A。 | ALUDataOut = ALUSrcA >> 1 |
shiftL; | 左移命令。针对的是源操作数A。 | ALUDataOut = ALUSrcA << 1 |
and; | ALUDataOut = ALUSrcA & ALUSrcB | |
or; | ALUDataOut = ALUSrcA | |
xor; | ALUDataOut = ALUSrcA ^ ALUSrcB | |
com; | 操作数B按位取反; | ALUDataOut=~ALUSrcB |
swp; | 16位翻转;双字节翻转; | ALUDataOut={ALUSrcB[15:0],ALUSrcB[31:16]} |
nop; | 空命令;结果等于源操作数B。 | ALUDataOut=ALUSrcB |
module ALU (// Input
ALUSrcA,//源操作数A
ALUSrcB,//源操作数B
OpCode,//8位指令码,来自IR。源是外部memory。
CurrentState,//CU控制单元的状态,就3个init、InstrFetch、InstrExec。
// Output
ALUDataOut//运算结果
);
CNTRL ControlUnit
- 内含FSM,可以参考状态机写法。二段式。
- CU控制单元的状态,就3个init、InstrFetch、InstrExec。
- -
module CNTRL ( // Input
clock,
reset,
OpCode,
ACCNeg,
ACCZero,
Grant,//PLL lock flag
// Ouptut
NextState,//4个状态。初始状态、取指、执行指令、指令暂停
PCInEn,
IRInEn,
ACCInEn,
ACCOutEn,
MemReq,
RdWrBar,
AddressSel,
ALUSrcBSel //ALU源操作数B,来源确定是地址还是数据。
);
待续
推荐文档:
- 【图文】单周期CPU及其Verilog_HDL实现_百度文库
http://wenku.baidu.com/link?url=TUXpFNBtzsmiCnTqI4AjQRIzJ8OauHzJqYT7jibbHeN1HDr9n-tHKJas-WDjAEC1C4rAeSpPRsdQSW-kO3t-Jf6-6H4nOcNE-Kf1DgG6WDG
- 程序计数器(Program Counter)是一个实际存在的寄存器吗? - 知乎
https://www.zhihu.com/question/22609253