代码不错, 讲解一般
我并未读完, 我只看了教学部分, 没看实践部分.
对讲解的评价
本书有一定讲解, 但是能讲得比较清楚的是教科书上的那些, 比如数据相关, 精确异常的定义是讲清楚了, ll, sc这些指令的作用也讲得比较明白. 但是对于代码, 我觉得讲解比较欠缺. 比如为什么需要if_id这样的模块? 我这个菜鸡很长时间内是不明白的(现在也没信心说完全明白了). 什么时候用组合逻辑, 什么时候用时序逻辑?
举个例子, 这是div.v中的一句话: result_o <= {dividend[64:33], dividend[31:0]}; 我关心的问题是, 为什么是dividend[64:33], 而不是dividend[63:32], 但是完全没讲. 也许这个是太细节了.
这样讲不透的例子到处都是, 比如div模块, 为什么这么设计? 错误状态是不是多余的? div模块比译码模块这种我觉得难多了, 但只有算法的介绍, 而完全没有状态机的讲解.
再举个例子, 第9章, mem模块, mem_sel_o其实对于load指令来说不是必要的, 它是由于save指令才存在的, 否则如果只存1字节, sb, 而ram又只支持写整个字, 那就得先读出来, 再写入, 这很慢! 但书上只说了mem_sel_o对load指令的意义是什么, 对save指令的意义是什么. 根本没有提到它对load不必要, 对save不可或缺.
再比如, 还是mem模块, 讲data_mem0, data_mem1这些都没提到这样设置的原因是大端法.
再举个例子:
if(current_inst_address_i != `ZeroWord) begin
if(((cp0_cause[15:8] & (cp0_status[15:8])) != 8'h00) && (cp0_status[1] == 1'b0) &&
(cp0_status[0] == 1'b1)) begin
excepttype_o <= 32'h00000001; //interrupt
end else if(excepttype_i[8] == 1'b1) begin
excepttype_o <= 32'h00000008; //syscall
end else if(excepttype_i[9] == 1'b1) begin
excepttype_o <= 32'h0000000a; //inst_invalid
end else if(excepttype_i[10] ==1'b1) begin
excepttype_o <= 32'h0000000d; //trap
end else if(excepttype_i[11] == 1'b1) begin //ov
excepttype_o <= 32'h0000000c;
end else if(excepttype_i[12] == 1'b1) begin //返回指令
excepttype_o <= 32'h0000000e;
end
end
为什么是这个判断顺序, 书里没说, 但其实是因为异常处理有优先级(不过书里给出了优先级表格).
或许作者认为太简单, 不谢需要讲, 但我觉得还是有必要讲解的. 我之前看《操作系统真象还原》, 尽管也有讲不透的地方, 但是能看出作者很明显是尽力想要讲明白. 这本书, 我都没感觉到作者有努力想要解释清楚.
关于代码的评价
- 端口比较清晰, 一个比较赞的地方是, 变量名, 如果是输入端口, 就会_i作为变量后缀, 输出端口会以_o为变量后缀.
- copy-on-paste的风格, 感觉可以用task复用代码的. 不过这有个优点就是, 这书看着有好几百页, 但是大部分我都跳过了, 因为都是重复的代码.
- 有些不影响理解的细节小错误, 比如msub指令的实现
`EXE_MSUB_OP, `EXE_MSUBU_OP: begin
if(cnt_i == 2'b00) begin
hilo_temp_o <= ~mulres + 1 ;
cnt_o <= 2'b01;
stallreq_for_madd_msub <= `Stop;
end else if(cnt_i == 2'b01)begin
hilo_temp_o <= {`ZeroWord,`ZeroWord};
cnt_o <= 2'b10;
hilo_temp1 <= hilo_temp_i + {HI,LO};
stallreq_for_madd_msub <= `NoStop;
end
这里msub干的事是{hi,lo}-stallreq_for_madd_msub. 但明明应该反过来. 手册里面描述了, 是: (LO,HI) ← (rs x rt) - (LO,HI)
再比如:
`EXE_LL_OP: begin
mem_addr_o <= mem_addr_i;
mem_we <= `WriteDisable;
wdata_o <= mem_data_i;
LLbit_we_o <= 1'b1;
LLbit_value_o <= 1'b1;
mem_sel_o <= 4'b1111;
mem_ce_o <= `ChipEnable;
end
这是mem对于ll的处理, 其实ll的处理应该是lw处理+设置LLbit相关, 这里没有考虑地址不是4字节对齐的情况, 根据手册, ll也需要判断是否对齐.
细节上可以改进的地方
连个结构图都不舍得放一张. 我希望每一章都有结构图, 事实上只有xori那一章有结构图, 后面只有增加的端口的接口图.
是否值得一读?
如果想要了解流水线cpu怎么工作, 还是值得一读的, 读了你就知道最简单的cpu还是可以比较简单的. 至少代码写得不错. 本书不涉及cache, MMU. 这样优秀的技术书太少了, 所以尽管我对它的讲解很不满意(高情商: 把思考的空间留给了读者), 还是觉得它值得计算机从业者的看一看.