我们已经了解RISC-V指令集
本次课内容:
回顾指令周期: 执行一条指令的步骤
单周期处理器的思想 - 一个周期内完成上述步骤
R
- 寄存器, M
- 存储器R
, M
, 选择器, 加法器, 移位器,
乘法器等
在类似YEMU的模拟器中也存在数据通路和控制信号的概念
inst_cycle()
可以看作是数据通路
以上是通用的设计方法, 可以用来设计任意模块, 例如总线, cache
功能需求=指令行为
, 就得到了单周期处理器设计流程
这对大家提出更高的要求
很多书籍把图画好, 甚至把代码写好, 直接阅读这类书籍并不能帮助大家锻炼上述技能
import chisel3._
import chisel3.util._
class YEMU extends Module {
val io = IO(new Bundle{ val halt = Output(Bool()) })
val R = Mem(32, UInt(64.W))
val PC = RegInit(0.U(64.W))
val M = Mem(1024 / 4, UInt(32.W))
def Rread(idx: UInt) = Mux(idx === 0.U, 0.U(64.W), R(idx))
val Ibundle = new Bundle {
val imm11_0 = UInt(12.W)
val rs1 = UInt( 5.W)
val funct3 = UInt( 3.W)
val rd = UInt( 5.W)
val opcode = UInt( 7.W)
}
def SignEXT(imm11_0: UInt) = Cat(Fill(52, imm11_0(11)), imm11_0)
val inst = M(PC(63, 2)).asTypeOf(Ibundle)
val isAddi = (inst.opcode === "b0010011".U) && (inst.funct3 === "b000".U)
val isEbreak = inst.asUInt === "x00100073".U
assert(isAddi || isEbreak, "Invalid instruction 0x%x", inst.asUInt)
val rs1Val = Rread(Mux(isEbreak, 10.U(5.W), inst.rs1))
val rs2Val = Rread(Mux(isEbreak, 11.U(5.W), 0.U(5.W)))
when (isAddi) { R(inst.rd) := rs1Val + SignEXT(inst.imm11_0) }
when (isEbreak && (rs1Val === 0.U)) { printf("%c", rs2Val(7,0)) }
io.halt := isEbreak && (rs1Val === 1.U)
PC := PC + 4.U
}
addi
和ebreak
两条指令的单周期处理器ebreak
输出字符的子功能需要仿真环境的支持,
不必在图中体现
如果你之前从来没有了解过单周期处理器设计, 强烈建议不要看书
大部分业界的RTL工程师都会本能地反对
大家需要承认
既然Verilog是一门编程语言, 就应该允许用户从编程角度评价它
是RTL设计语言?
不, Verilog的本质是一门事件建模语言
用Verilog来设计可综合电路是后来的事情
# 30
最匪夷所思: “可综合”的内涵和外延都没有标准规范!
实际情况
*
, /
和%
一般不用,
它们综合出的是在一个周期内得到结果的复杂电路, 面积, 功耗,
延迟都很大尽管大部分综合器都这么约定, 但终究没有统一的标准依据
但为了描述时序逻辑元件, 只能用行为建模
Verilog本来是一门事件建模语言, 引入always是很自然的
但用来做RTL设计, 麻烦就来了
=
和<=
混用, 综合器是要支持的
这好比一些过时的x86指令已经不用了, 但硬件设计者还要实现它们
行为建模的设计过程:
从第2步就已经开始偏离RTL设计的初衷:
行为建模的设计过程:
更可怕的是直接从第2步开始
本质区别: 用电路实现需求 vs. 用事件模型实现需求
你可以很容易在课本等学习资料中找到类似的描述:
在Verilog中,各语句是并发执行的,模块中所有的assign语句、always语句块和实例化语句,其执行顺序不分
先后。而if语句是顺序执行的语句,其执行过程中必须先判断if后的条件,如果满足条件则执行if后的语句,否则
执行else后的语句。Verilog语法规定,顺序执行的语句必须包含中always块中,always块中的语句按照它们
在代码中出现的顺序执行。
如果你觉得它是对的(确实是对的), 你很有可能已经开始被误导了:
if的条件满足, 就不执行else后的语句
, 这里的
“不执行”又是什么意思? 和描述电路有什么联系?并发执行
, 又有顺序执行
,
还有任何一个变量发生变化就立即执行
,
以及在任何情况下都执行
, 它们都是如何在电路中体现的?估计大部分教Verilog的老师都无法对这些问题作出明确的回答 😂
有的企业限制always中的编码风格, 有的企业甚至不允许写always
大部分RTL工程师认为Verilog的这些问题在实际中不是问题, 是因为他们无法全面地评价一门语言
当我们讨论PPA的时候, 针对的是电路, 而不是模型
RTL设计 = 直接描述电路结构 = 实例化 + 连线
用数据流建模和结构化建模就可以实现
为了支持触发器/存储器, 可以写一个参数化的module
负责从指令生成控制信号
都是同一个设计, 但怎么写代码又是另一回事
assign SB = (IR[31] & ~IR[30] & IR[29] & ~IR[28] & ~IR[27] & ~IR[26]);
assign SH = (IR[31] & ~IR[30] & IR[29] & ~IR[28] & ~IR[27] & IR[26]);
assign SWR = (IR[31] & ~IR[30] & IR[29] & IR[28] & IR[27] & ~IR[26]);
assign SWL = (IR[31] & ~IR[30] & IR[29] & ~IR[28] & IR[27] & ~IR[26]);
assign SRL = (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & ~IR[5] & ~IR[4] & ~IR[3] & ~IR[2] & IR[1] & ~IR[0]);
assign SRA = (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & ~IR[5] & ~IR[4] & ~IR[3] & ~IR[2] & IR[1] & IR[0]);
assign Ext0 = (~IR[31] & ~IR[30] & IR[29] & IR[28] & ~IR[27] & IR[26]) | (~IR[31] & ~IR[30] & IR[29] & IR[28] & ~IR[27] & ~IR[26]) | (~IR[31] & ~IR[30] & IR[29] & IR[28] & IR[27] & ~IR[26]);
assign Wtrs = ((Zero == 1'b0) & (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & ~IR[5] & ~IR[4] & IR[3] & ~IR[2] & IR[1] & IR[0])) | ((Zero == 1'b1) & (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & ~IR[5] & ~IR[4] & IR[3] & ~IR[2] & IR[1] & ~IR[0]));
assign LWLR1 = (IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & IR[27] & ~IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & IR[28] & IR[27] & ~IR[26]) | (IR[31] & ~IR[30] & IR[29] & ~IR[28] & IR[27] & ~IR[26]) | (IR[31] & ~IR[30] & IR[29] & IR[28] & IR[27] & ~IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & IR[28] & ~IR[27] & ~IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & IR[28] & ~IR[27] & IR[26]) | (IR[31] & ~IR[30] & IR[29] & ~IR[28] & ~IR[27] & ~IR[26]) | (IR[31] & ~IR[30] & IR[29] & ~IR[28] & ~IR[27] & IR[26]);
assign LWLR2 = (IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & IR[27] & ~IR[26]);
assign LWLR3 = (IR[31] & ~IR[30] & ~IR[29] & IR[28] & IR[27] & ~IR[26]);
assign LHU = (IR[31] & ~IR[30] & ~IR[29] & IR[28] & ~IR[27] & IR[26]);
assign LH = (IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & IR[26]);
assign LBU = (IR[31] & ~IR[30] & ~IR[29] & IR[28] & ~IR[27] & ~IR[26]);
assign LB = (IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26]);
assign ZeroJg = (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & IR[26] & ~IR[20] & ~IR[19] & ~IR[18] & ~IR[17] & IR[16]) | (~IR[31] & ~IR[30] & ~IR[29] & IR[28] & IR[27] & ~IR[26]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & IR[26] & ~IR[20] & ~IR[19] & ~IR[18] & ~IR[17] & ~IR[16]) | (IR[31:26] == 6'b000111);
assign RegDst = (~IR[31] & ~IR[30] & IR[29] & ~IR[28] & ~IR[27] & IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & IR[27] & IR[26]) | (~IR[31] & ~IR[30] & IR[29] & IR[28] & IR[27] & IR[26]) | (~IR[31] & ~IR[30] & IR[29] & ~IR[28] & IR[27] & ~IR[26]) | (~IR[31] & ~IR[30] & IR[29] & ~IR[28] & IR[27] & IR[26]) | (~IR[31] & ~IR[30] & IR[29] & IR[28] & ~IR[27] & ~IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & IR[28] & ~IR[27] & ~IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & IR[28] & ~IR[27] & IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & IR[27] & ~IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & IR[28] & IR[27] & ~IR[26]) | (~IR[31] & ~IR[30] & IR[29] & IR[28] & ~IR[27] & IR[26]) | (~IR[31] & ~IR[30] & IR[29] & IR[28] & IR[27] & ~IR[26]);
assign ALUSrc = (~IR[31] & ~IR[30] & ~IR[29] & IR[28] & ~IR[27] & IR[26]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & IR[5] & ~IR[4] & ~IR[3] & ~IR[2] & ~IR[1] & IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & IR[28] & ~IR[27] & ~IR[26]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & IR[5] & ~IR[4] & ~IR[3] & IR[2] & ~IR[1] & IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & IR[5] & ~IR[4] & IR[3] & ~IR[2] & IR[1] & ~IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & IR[5] & ~IR[4] & ~IR[3] & ~IR[2] & IR[1] & IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & IR[5] & ~IR[4] & ~IR[3] & IR[2] & ~IR[1] & ~IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & ~IR[5] & ~IR[4] & IR[3] & ~IR[2] & IR[1] & IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & ~IR[5] & ~IR[4] & IR[3] & ~IR[2] & IR[1] & ~IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & IR[5] & ~IR[4] & ~IR[3] & IR[2] & IR[1] & IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & ~IR[5] & ~IR[4] & ~IR[3] & IR[2] & ~IR[1] & ~IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & IR[5] & ~IR[4] & IR[3] & ~IR[2] & IR[1] & IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & ~IR[5] & ~IR[4] & ~IR[3] & IR[2] & IR[1] & IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & ~IR[5] & ~IR[4] & ~IR[3] & IR[2] & IR[1] & ~IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & IR[5] & ~IR[4] & ~IR[3] & IR[2] & IR[1] & ~IR[0]);
assign PCSrc = ((~(Zero == 1)) & (~IR[31] & ~IR[30] & ~IR[29] & IR[28] & ~IR[27] & IR[26])) | ((Zero == 1) & (~IR[31] & ~IR[30] & ~IR[29] & IR[28] & ~IR[27] & ~IR[26])) | ((Address == 32'h00000000) & (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & IR[26] & ~IR[20] & ~IR[19] & ~IR[18] & ~IR[17] & IR[16])) | (((Address == 32'h00000001) | (Read1 == 32'h00000000)) & (~IR[31] & ~IR[30] & ~IR[29] & IR[28] & IR[27] & ~IR[26])) | ((Address == 32'h00000001) & (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & IR[26] & ~IR[20] & ~IR[19] & ~IR[18] & ~IR[17] & ~IR[16])) | (Address == 32'h0 & ~(Read1 == 32'h0) & IR[31:26] == 6'b000111);
// assign RegWrite = (~IR[31] & ~IR[30] & IR[29] & ~IR[28] & ~IR[27] & IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & IR[27] & IR[26]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & IR[5] & ~IR[4] & ~IR[3] & ~IR[2] & ~IR[1] & IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & IR[5] & ~IR[4] & ~IR[3] & IR[2] & ~IR[1] & IR[0]) | (~IR[31] & ~IR[30] & IR[29] & IR[28] & IR[27] & IR[26]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & ~IR[5] & ~IR[4] & ~IR[3] & ~IR[2] & ~IR[1] & ~IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & IR[5] & ~IR[4] & IR[3] & ~IR[2] & IR[1] & ~IR[0]) | (~IR[31] & ~IR[30] & IR[29] & ~IR[28] & IR[27] & ~IR[26]) | (~IR[31] & ~IR[30] & IR[29] & ~IR[28] & IR[27] & IR[26]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & IR[5] & ~IR[4] & ~IR[3] & ~IR[2] & IR[1] & IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & IR[27] & IR[26]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & IR[5] & ~IR[4] & ~IR[3] & IR[2] & ~IR[1] & ~IR[0]) | (~IR[31] & ~IR[30] & IR[29] & IR[28] & ~IR[27] & ~IR[26]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & ~IR[5] & ~IR[4] & IR[3] & ~IR[2] & ~IR[1] & IR[0]) | (IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & IR[28] & ~IR[27] & ~IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & IR[28] & ~IR[27] & IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & IR[27] & ~IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & IR[28] & IR[27] & ~IR[26]) | ((Zero == 1'b0) & (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & ~IR[5] & ~IR[4] & IR[3] & ~IR[2] & IR[1] & IR[0])) | ((Zero == 1'b1) & (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & ~IR[5] & ~IR[4] & IR[3] & ~IR[2] & IR[1] & ~IR[0])) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & IR[5] & ~IR[4] & ~IR[3] & IR[2] & IR[1] & IR[0]) | (~IR[31] & ~IR[30] & IR[29] & IR[28] & ~IR[27] & IR[26]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & ~IR[5] & ~IR[4] & ~IR[3] & IR[2] & ~IR[1] & ~IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & IR[5] & ~IR[4] & IR[3] & ~IR[2] & IR[1] & IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & ~IR[5] & ~IR[4] & ~IR[3] & ~IR[2] & IR[1] & IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & ~IR[5] & ~IR[4] & ~IR[3] & IR[2] & IR[1] & IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & ~IR[5] & ~IR[4] & ~IR[3] & ~IR[2] & IR[1] & ~IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & ~IR[5] & ~IR[4] & ~IR[3] & IR[2] & IR[1] & ~IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & IR[5] & ~IR[4] & ~IR[3] & IR[2] & IR[1] & ~IR[0]) | (~IR[31] & ~IR[30] & IR[29] & IR[28] & IR[27] & ~IR[26]);
assign Jmp = (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & IR[27] & ~IR[26]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & IR[27] & IR[26]);
// assign MemWrite = (IR[31] & ~IR[30] & IR[29] & ~IR[28] & IR[27] & IR[26]) | (IR[31] & ~IR[30] & IR[29] & ~IR[28] & ~IR[27] & ~IR[26]) | (IR[31] & ~IR[30] & IR[29] & ~IR[28] & ~IR[27] & IR[26]) | (IR[31] & ~IR[30] & IR[29] & ~IR[28] & IR[27] & ~IR[26]) | (IR[31] & ~IR[30] & IR[29] & IR[28] & IR[27] & ~IR[26]);
// assign MemRead = (IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & IR[27] & IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & IR[28] & ~IR[27] & ~IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & IR[28] & ~IR[27] & IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & IR[27] & ~IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & IR[28] & IR[27] & ~IR[26]);
assign MemtoReg = (IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & IR[27] & IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & IR[28] & ~IR[27] & ~IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & IR[28] & ~IR[27] & IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & IR[27] & ~IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & IR[28] & IR[27] & ~IR[26]);
assign SLL = (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & ~IR[5] & ~IR[4] & ~IR[3] & ~IR[2] & ~IR[1] & ~IR[0]);
assign JAL1 = (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & IR[27] & IR[26]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & ~IR[5] & ~IR[4] & IR[3] & ~IR[2] & ~IR[1] & IR[0]);
assign JAL2 = (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & IR[27] & IR[26]);
assign JR = (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & ~IR[5] & ~IR[4] & IR[3] & ~IR[2] & ~IR[1] & ~IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & ~IR[5] & ~IR[4] & IR[3] & ~IR[2] & ~IR[1] & IR[0]);
assign Write_strb[3] = (IR[31] & ~IR[30] & IR[29] & ~IR[28] & IR[27] & IR[26]) | (ALUResult[1] & ALUResult[0] & IR[31] & ~IR[30] & IR[29] & ~IR[28] & ~IR[27] & ~IR[26]) | (ALUResult[1] & IR[31] & ~IR[30] & IR[29] & ~IR[28] & ~IR[27] & IR[26]) | (ALUResult[1] & ALUResult[0] & IR[31] & ~IR[30] & IR[29] & ~IR[28] & IR[27] & ~IR[26]) | (IR[31] & ~IR[30] & IR[29] & IR[28] & IR[27] & ~IR[26]);
assign Write_strb[2] = (IR[31] & ~IR[30] & IR[29] & ~IR[28] & IR[27] & IR[26]) | (ALUResult[1] & ~ALUResult[0] & IR[31] & ~IR[30] & IR[29] & ~IR[28] & ~IR[27] & ~IR[26]) | (ALUResult[1] & IR[31] & ~IR[30] & IR[29] & ~IR[28] & ~IR[27] & IR[26]) | (ALUResult[1] & IR[31] & ~IR[30] & IR[29] & ~IR[28] & IR[27] & ~IR[26]) | (~ALUResult[1] & IR[31] & ~IR[30] & IR[29] & ~IR[28] & IR[27] & ~IR[26]) | (ALUResult[1] & ~ALUResult[0] & IR[31] & ~IR[30] & IR[29] & ~IR[28] & IR[27] & ~IR[26]);
assign Write_strb[1] = (IR[31] & ~IR[30] & IR[29] & ~IR[28] & IR[27] & IR[26]) | (~ALUResult[1] & ALUResult[0] & IR[31] & ~IR[30] & IR[29] & ~IR[28] & ~IR[27] & ~IR[26]) | (~ALUResult[1] & IR[31] & ~IR[30] & IR[29] & ~IR[28] & ~IR[27] & IR[26]) | (ALUResult[1] & IR[31] & ~IR[30] & IR[29] & ~IR[28] & IR[27] & ~IR[26]) | (~ALUResult[1] & ALUResult[0] & IR[31] & ~IR[30] & IR[29] & ~IR[28] & IR[27] & ~IR[26]) | (~ALUResult[1] & IR[31] & ~IR[30] & IR[29] & ~IR[28] & IR[27] & ~IR[26]);
assign Write_strb[0] = (IR[31] & ~IR[30] & IR[29] & ~IR[28] & IR[27] & IR[26]) | (~ALUResult[1] & ~ALUResult[0] & IR[31] & ~IR[30] & IR[29] & ~IR[28] & ~IR[27] & ~IR[26]) | (~ALUResult[1] & IR[31] & ~IR[30] & IR[29] & ~IR[28] & ~IR[27] & IR[26]) | (IR[31] & ~IR[30] & IR[29] & ~IR[28] & IR[27] & ~IR[26]) | (~ALUResult[1] & ~ALUResult[0] & IR[31] & ~IR[30] & IR[29] & ~IR[28] & IR[27] & ~IR[26]);
assign ALUctr[3] = (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & IR[5] & ~IR[4] & ~IR[3] & IR[2] & IR[1] & IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & ~IR[5] & ~IR[4] & ~IR[3] & IR[2] & ~IR[1] & ~IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & ~IR[5] & ~IR[4] & ~IR[3] & IR[2] & IR[1] & IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & ~IR[5] & ~IR[4] & ~IR[3] & IR[2] & IR[1] & ~IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & IR[5] & ~IR[4] & ~IR[3] & IR[2] & IR[1] & ~IR[0]) | (~IR[31] & ~IR[30] & IR[29] & IR[28] & IR[27] & ~IR[26]);
assign ALUctr[2] = (~IR[31] & ~IR[30] & ~IR[29] & IR[28] & ~IR[27] & IR[26]) | (~IR[31] & ~IR[30] & ~IR[29] & IR[28] & ~IR[27] & ~IR[26]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & IR[5] & ~IR[4] & IR[3] & ~IR[2] & IR[1] & ~IR[0]) | (~IR[31] & ~IR[30] & IR[29] & ~IR[28] & IR[27] & ~IR[26]) | (~IR[31] & ~IR[30] & IR[29] & ~IR[28] & IR[27] & IR[26]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & IR[5] & ~IR[4] & ~IR[3] & ~IR[2] & IR[1] & IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & IR[26] & ~IR[20] & ~IR[19] & ~IR[18] & ~IR[17] & IR[16]) | (~IR[31] & ~IR[30] & ~IR[29] & IR[28] & IR[27] & ~IR[26]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & IR[26] & ~IR[20] & ~IR[19] & ~IR[18] & ~IR[17] & ~IR[16]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & ~IR[5] & ~IR[4] & IR[3] & ~IR[2] & IR[1] & IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & ~IR[5] & ~IR[4] & IR[3] & ~IR[2] & IR[1] & ~IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & IR[5] & ~IR[4] & IR[3] & ~IR[2] & IR[1] & IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & ~IR[5] & ~IR[4] & ~IR[3] & IR[2] & IR[1] & IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & IR[5] & ~IR[4] & ~IR[3] & IR[2] & IR[1] & ~IR[0]) | (~IR[31] & ~IR[30] & IR[29] & IR[28] & IR[27] & ~IR[26]) | (IR[31:26] == 6'b000111);
assign ALUctr[1] = (~IR[31] & ~IR[30] & IR[29] & ~IR[28] & ~IR[27] & IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & IR[27] & IR[26]) | (IR[31] & ~IR[30] & IR[29] & ~IR[28] & IR[27] & IR[26]) | (~IR[31] & ~IR[30] & ~IR[29] & IR[28] & ~IR[27] & IR[26]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & IR[5] & ~IR[4] & ~IR[3] & ~IR[2] & ~IR[1] & IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & IR[28] & ~IR[27] & ~IR[26]) | (~IR[31] & ~IR[30] & IR[29] & IR[28] & IR[27] & IR[26]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & IR[5] & ~IR[4] & IR[3] & ~IR[2] & IR[1] & ~IR[0]) | (~IR[31] & ~IR[30] & IR[29] & ~IR[28] & IR[27] & ~IR[26]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & IR[5] & ~IR[4] & ~IR[3] & ~IR[2] & IR[1] & IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & IR[26] & ~IR[20] & ~IR[19] & ~IR[18] & ~IR[17] & IR[16]) | (~IR[31] & ~IR[30] & ~IR[29] & IR[28] & IR[27] & ~IR[26]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & IR[26] & ~IR[20] & ~IR[19] & ~IR[18] & ~IR[17] & ~IR[16]) | (IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & IR[28] & ~IR[27] & ~IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & IR[28] & ~IR[27] & IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & IR[27] & ~IR[26]) | (IR[31] & ~IR[30] & ~IR[29] & IR[28] & IR[27] & ~IR[26]) | (IR[31] & ~IR[30] & IR[29] & ~IR[28] & ~IR[27] & ~IR[26]) | (IR[31] & ~IR[30] & IR[29] & ~IR[28] & ~IR[27] & IR[26]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & ~IR[5] & ~IR[4] & ~IR[3] & IR[2] & IR[1] & ~IR[0]) | (IR[31] & ~IR[30] & IR[29] & ~IR[28] & IR[27] & ~IR[26]) | (IR[31] & ~IR[30] & IR[29] & IR[28] & IR[27] & ~IR[26]) | (IR[31:26] == 6'b000111);
assign ALUctr[0] = (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & IR[5] & ~IR[4] & ~IR[3] & IR[2] & ~IR[1] & IR[0]) | (~IR[31] & ~IR[30] & IR[29] & IR[28] & IR[27] & IR[26]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & IR[5] & ~IR[4] & IR[3] & ~IR[2] & IR[1] & ~IR[0]) | (~IR[31] & ~IR[30] & IR[29] & ~IR[28] & IR[27] & ~IR[26]) | (~IR[31] & ~IR[30] & IR[29] & ~IR[28] & IR[27] & IR[26]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & IR[26] & ~IR[20] & ~IR[19] & ~IR[18] & ~IR[17] & IR[16]) | (~IR[31] & ~IR[30] & ~IR[29] & IR[28] & IR[27] & ~IR[26]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & IR[26] & ~IR[20] & ~IR[19] & ~IR[18] & ~IR[17] & ~IR[16]) | (~IR[31] & ~IR[30] & IR[29] & IR[28] & ~IR[27] & IR[26]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & ~IR[5] & ~IR[4] & ~IR[3] & IR[2] & ~IR[1] & ~IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & IR[5] & ~IR[4] & IR[3] & ~IR[2] & IR[1] & IR[0]) | (~IR[31] & ~IR[30] & ~IR[29] & ~IR[28] & ~IR[27] & ~IR[26] & IR[5] & ~IR[4] & ~IR[3] & IR[2] & IR[1] & ~IR[0]) | (~IR[31] & ~IR[30] & IR[29] & IR[28] & IR[27] & ~IR[26]) | (IR[31:26] == 6'b000111);
6'b001010://slti
begin
RegDst <= 0;
ALUSrc <= 1;
Branch <= 0;
RegWrite <= 0;
RegRead <= 1;
MemtoReg <= 0;
//MemRead <= 0;
//MemWrite <= 0;
Write_strb <= 4'd0;
ALUcon_in <= 3'b010;
Jump <= 0;
JumpReg <= 0;
JAL <= 0;
LUI <= 0;
SL <= 0;
s <= 0;
Sign <= 1;
BEQ <= 0;
BGEZ <= 0;
BGTZ <= 0;
BLEZ <= 0;
BLTZ <= 0;
Logic <= 0;
Left <= 0;
JALR <= 0;
Align <= 0;
Part_data <= 32'd0;
end
6'b001011://sltiu
begin
RegDst <= 0;
ALUSrc <= 1;
Branch <= 0;
RegWrite <= 0;
RegRead <= 1;
MemtoReg <= 0;
//MemRead <= 0;
//MemWrite <= 0;
Write_strb <= 4'd0;
ALUcon_in <= 3'b011;
Jump <= 0;
JumpReg <= 0;
JAL <= 0;
LUI <= 0;
SL <= 0;
s <= 0;
Sign <= 0;
BEQ <= 0;
BGEZ <= 0;
BGTZ <= 0;
BLEZ <= 0;
BLTZ <= 0;
Logic <= 0;
Left <= 0;
JALR <= 0;
Align <= 0;
Part_data <= 32'd0;
end
类似的代码有1500行
如何拥抱变化
灵魂拷问
正确的代码 != 好代码
好代码的两条重要准则
使用正确的编程模式写出好代码
assert
检查非预期行为分析: 译码器的本质是查找表
需求: 如何 “低熵”地实现一张表?
我们需要寻找合适的语言特性来实现一张表
太难了 😂
我们提供一个键值选择模板muxkey-template.v, 可以像真值表一样查询
module mux41(a,s,y);
input [3:0] a;
input [1:0] s;
output y;
// 通过MuxKeyWithDefault实现如下always代码
// always @(*) begin
// case (s)
// 2'b00: y = a[0];
// 2'b01: y = a[1];
// 2'b10: y = a[2];
// 2'b11: y = a[3];
// default: y = 1'b0;
// endcase
// end
MuxKeyWithDefault #(4, 2, 1) i0 (y, s, 1'b0, {
2'b00, a[0],
2'b01, a[1],
2'b10, a[2],
2'b11, a[3]
});
endmodule
但还是有很多不完善的地方
casex
和casez
在建模语义上支持模糊匹配
案例: 第一届龙芯杯(2017), 南京大学一队通过excel和python脚本, 实现译码器的敏捷开发和低熵维护
借助scala的强大类型系统, 把表格嵌入到Chisel代码中
object RV64IInstr extends HasInstrType {
def ADDIW = BitPat("b???????_?????_?????_000_?????_0011011")
def SLLIW = BitPat("b0000000_?????_?????_001_?????_0011011")
def SRLIW = BitPat("b0000000_?????_?????_101_?????_0011011")
def SRAIW = BitPat("b0100000_?????_?????_101_?????_0011011")
def SLLW = BitPat("b0000000_?????_?????_001_?????_0111011")
def SRLW = BitPat("b0000000_?????_?????_101_?????_0111011")
def SRAW = BitPat("b0100000_?????_?????_101_?????_0111011")
def ADDW = BitPat("b0000000_?????_?????_000_?????_0111011")
def SUBW = BitPat("b0100000_?????_?????_000_?????_0111011")
def LWU = BitPat("b???????_?????_?????_110_?????_0000011")
def LD = BitPat("b???????_?????_?????_011_?????_0000011")
def SD = BitPat("b???????_?????_?????_011_?????_0100011")
val table = Array(
ADDIW -> List(InstrI, FuType.alu, ALUOpType.addw),
SLLIW -> List(InstrI, FuType.alu, ALUOpType.sllw),
SRLIW -> List(InstrI, FuType.alu, ALUOpType.srlw),
SRAIW -> List(InstrI, FuType.alu, ALUOpType.sraw),
SLLW -> List(InstrR, FuType.alu, ALUOpType.sllw),
SRLW -> List(InstrR, FuType.alu, ALUOpType.srlw),
SRAW -> List(InstrR, FuType.alu, ALUOpType.sraw),
ADDW -> List(InstrR, FuType.alu, ALUOpType.addw),
SUBW -> List(InstrR, FuType.alu, ALUOpType.subw),
LWU -> List(InstrI, FuType.lsu, LSUOpType.lwu),
LD -> List(InstrI, FuType.lsu, LSUOpType.ld ),
SD -> List(InstrS, FuType.lsu, LSUOpType.sd)
)
}
用法和ListLookup几乎相同, 但有额外好处
核心思想: 借助工具生成精准的电路描述, 将不确定的综合器行为前移到设计阶段
方案 | 容易维护 | 综合精确 |
---|---|---|
逻辑表达式 | ✖️✖️ | ✔️✔️ |
case语句 | ✖️ | ✖️ |
excel + python | ✔️✔️ | ✖️ |
Chisel ListLookup | ✔️✔️ | ✔️ |
Chisel Decoder | ✔️✔️ | ✔️✔️ |