合肥工业大学计组实验五
step1 分析命令:
这十条命令为:CLA、COM、SHR、CSL、STP、ADD、STA、LDA、JMP、BAN
实现这些命令所需的模块有:PC、ACC、ALU、CU、ROM、RAM
step2 分析模块:
PC
由于PC需要增加停机功能和跳转功能,所以PC应该增加接口来实现停机与跳转指令。
ACC
新增模块ACC,ACC为累加器,CLA、COM、SHR、CSL这四条指令直接操作ACC中的数据,ADD指令将ACC作为操作数,所以ACC应该有一个读数据、一个写数据、使写数据能的接口。(后期实验发现忘记给ACC加一个时钟控制信号了,不加时钟控制信号的话ACC中的数据会出错,一个时钟周期内可能被写两次。)
CU
由于CU要控制ACC和PC完成指令,所以CU应该增加输出来控制ACC和PC。
ALU
ALU需要完成对ACC最高位的判断,并将判断结果传送给PC以便PC完成BAN指令。
其余模块无需改变
step3 新增模块图示:
step4 cpu数据通路设计:
除了图中画红线的其余名字一样的连到一起。
Step5 指令设计:
这次实验我将指令的位数更改为13位,[12:9]为操作码,[8:0]为立即数或地址。
Step6 模块设计:
PC:
1. module PC(
2. input clk,
3. input rst,
4. input stop,
5. input ban,
6. input p_wr_en,
7. input wire [12:0] jmp,
8. output reg [12:0] pc
9. );
10. reg state;
11. initial begin
12. pc=8'd0;
13. state=1;
14. end
15. always@* begin
16. if(stop==1)
17. state<=0;
18. if(rst==1)
19. pc<=0;
20. end
21. always@(posedge clk) begin
22. if(state==1)
23. pc<=pc+1'd1;
24. end
25. always@(negedge clk) begin
26. if(p_wr_en==1)
27. pc<=jmp-1;
28. if(ban==1)
29. pc<=pc+jmp-1;
30. end
31. endmodule
ROM:
1. module ROM(
2. input wire [12:0] pc,
3. output reg [15:0] ins
4. );
5.
6. reg [15:0] ROM_data [255:0];
7. integer i;
8.
9. initial $readmemb("D:/vivadowork/TEN-CPU/ONE_CPU.srcs/sources_1/new/ROM_initial.txt",ROM_data);
10.
11. always@(pc) begin
12. ins<=ROM_data[pc];
13. end
14. endmodule
RAM:
1. module RAM(
2. input clk,
3. input m_wr_en,
4. input wire [15:0] in_data,
5. input wire [8:0] index,
6. output wire [15:0] out_data
7. );
8.
9. reg [15:0] initdata [1023:0];
10. integer i;
11. initial $readmemb("D:/vivadowork/TEN-CPU/ONE_CPU.srcs/sources_1/new/RAM_initial.txt",initdata);
12.
13. always@(posedge clk ) begin
14. begin if (m_wr_en==0)
15. initdata[index]<=in_data;
16. end
17. end
18.
19. assign out_data=initdata[index];
20. endmodule
CU:
根据不同指令输出不同的数据来控制各个模块来完成指令。
1. module CU(
2. input wire [3:0] opcode,
3. output reg p_wr_en,
4. output reg m_wr_en,
5. output reg a_wr_en,
6.
7. output reg stop,
8. output reg [3:0] alu_op
9. );
10. always@(opcode)begin
11. case(opcode)
12. 4'b0001: begin //cla
13. p_wr_en<=0;
14. stop<=0;
15. m_wr_en<=1;
16. a_wr_en<=1;
17. alu_op<=4'b0111;
18. end
19. 4'b0010: begin//com
20. p_wr_en<=0;
21. stop<=0;
22. m_wr_en<=1;
23. a_wr_en<=1;
24. alu_op<=4'b1000;
25. end
26. 4'b0011: begin //shr
27. p_wr_en<=0;
28. stop<=0;
29. m_wr_en<=1;
30. a_wr_en<=1;
31. alu_op<=4'b1001;
32. end
33. 4'b0100: begin //csl
34. p_wr_en<=0;
35. stop<=0;
36. m_wr_en<=1;
37. a_wr_en<=1;
38. alu_op<=4'b1010;
39. end
40. 4'b0101: begin //stp
41. p_wr_en<=0;
42. stop<=1;
43. m_wr_en<=1;
44. a_wr_en<=0;
45. end
46. 4'b0110: begin //add
47. p_wr_en<=0;
48. stop<=0;
49. m_wr_en<=1;
50. a_wr_en<=1;
51. alu_op<=4'b0001;
52. end
53. 4'b0111: begin //sta
54. p_wr_en<=0;
55. stop<=0;
56. m_wr_en<=0;
57. a_wr_en<=0;
58.
59. end
60. 4'b1000: begin //lda
61. p_wr_en<=0;
62. stop<=0;
63. m_wr_en<=1;
64. a_wr_en<=1;
65. alu_op<=4'b1011;
66. end
67. 4'b1001: begin //jmp
68. p_wr_en<=1;
69. stop<=0;
70. m_wr_en<=1;
71. a_wr_en<=0;
72. end
73. 4'b1010: begin //ban
74. p_wr_en<=1;
75. stop<=0;
76. m_wr_en<=1;
77. a_wr_en<=0;
78. alu_op<=4'b1100;
79. end
80. endcase
81. end
82. endmodule
ALU:
1. module ALU(
2. input wire[15:0] in1,
3. input wire[15:0] in2,
4. input wire[3:0] alu_op,
5. output reg ban,
6. output reg[15:0] z
7. );
8. always @(*)
9. begin
10. case(alu_op)
11. 4'b0001: z<=in1+in2;
12. 4'b0010: z<=in1-in2;
13. 4'b0011: z<=in1&in2;
14. 4'b0100: z<=in1|in2;
15. 4'b0101: z<=in1<<in2;
16. 4'b0110: z<=in1>>in2;
17. 4'b0111: z<=0; //cla
18. 4'b1000: z<=~in1; //com
19. 4'b1001: z<={{in1[15]},in1[15:1]}; //shr
20. 4'b1010: z<={{in1[14:0]},in1[15]}; //csl
21. 4'b1011: z<=in2;
22. 4'b1100: ban<=in1[15]==1 ? 1 : 0;
23. // 4'b0111: z<={{6{imm[8]}},imm}+in1;
24. // 4'b1000: z<=out_data;
25. endcase
26. end
27. endmodule
ACC:
1. module ACC(
2. input a_wr_en,
3. input clk,
4. input wire [15:0]in_data,
5. output wire [15:0]acc_data
6. );
7. reg [0:15]acc;
8. initial begin
9. acc=16'd0;
10. end
11. assign acc_data=acc;
12. always@( posedge clk)
13. begin
14. if(a_wr_en==1)
15. acc=in_data;
16. end
17.
18.
19. endmodule
顶层封装:
1. module CPU(
2. input clk,
3. input rst,
4. output stop,
5. output ban,
6. output p_wr_en,
7. output a_wr_en,
8. output wire [12:0] pc,
9. output wire [15:0] ins,
10. output wire [3:0] alu_op,
11. output m_wr_en,
12. output wire [15:0] z,
13. output wire [15:0]acc_data,
14. output wire [15:0]out_data
15. );
16.
17.
18. PC f_pc(
19. .clk(clk),
20. .rst(rst),
21. .pc(pc),
22. .stop(stop),
23. .ban(ban),
24. .p_wr_en(p_wr_en),
25. .jmp({{4{ins[8]}},ins[8:0]}));
26.
27. ROM f_rom(
28. .pc(pc),
29. .ins(ins));
30.
31. RAM f_ram(
32. .clk(clk),
33. .m_wr_en(m_wr_en),
34. .in_data(acc_data),
35. .index(ins[8:0]),
36. .out_data(out_data)
37. );
38.
39. CU f_cu(
40. .opcode(ins[12:9]),
41. .p_wr_en(p_wr_en),
42. .a_wr_en(a_wr_en),
43. .stop(stop),
44. .alu_op(alu_op),
45. .m_wr_en(m_wr_en) //
46. );
47.
48. ALU f_alu(
49. .ban(ban),
50. .in1(acc_data),
51. .in2(out_data),
52. .alu_op(alu_op),
53. .z(z)
54. );
55.
56. ACC f_acc(
57. .a_wr_en(a_wr_en),
58. .clk(clk),
59. .in_data(z),
60. .acc_data(acc_data)
61. );
62. endmodule
Step6 模拟仿真
1. 仿真文件
1. module test_CPU;
2. reg clk;
3. reg rst;
4. wire stop;
5. wire ban;
6. wire p_wr_en;
7. wire a_wr_en;
8. wire [12:0] pc;
9. wire [12:0] ins;
10. wire m_wr_en;
11. wire [3:0] alu_op;
12. wire [15:0] z;
13. wire [15:0] out_data;
14. wire [15:0] acc_data;
15.
16. initial begin
17. clk=1'd0;
18. forever #10 clk=~clk;
19. end
20.
21. initial begin
22. rst=1'd0;
23. #120 $stop;
24. end
25.
26. CPU test(
27. .clk(clk),
28. .rst(rst),
29. .stop(stop),
30. .ban(ban),
31. .p_wr_en(p_wr_en),
32. .acc_data(acc_data),
33. .z(z),
34. .pc(pc),
35. .ins(ins),
36. .a_wr_en(a_wr_en),
37. .alu_op(alu_op),
38. .m_wr_en(m_wr_en),
39. .out_data(out_data)
40. );
41. endmodule
2. 仿真:
(一)第一次仿真
ROM初始化数据为:
1000000000001 //lda
0010000000000 //com
0011000000000 //shr
0001000000000 //cla
0101000000000 //stp
RAM初始化数据为:
1010001111010100
0000110101110011
仿真结果:
(二)第二次仿真
ROM初始化数据为:
1000000000000 //lda
0110000000001 //add
0111000000000 //sta
1000000000011 //lda
1010000000010 //ban
0101000000000 //stp
1001000001000 //jmp
0101000000000 //stp
RAM初始化数据为:
1010001111010100
0000110101110011
0000000000000010
1111111111111111
0001000000000000
在执行这些指令的过程中我发现了一些错误所以将代码修改了一下:
修改如下:
一.当执行ban指令跳转后,ban值一直为1,所以pc一直在执行ban操作,所以要在ALU的其他操作中增加ban输出为0的操作防止出错。同时cu中有一些操作没有对应的ALU操作为防止执行ban指令后出错,更改cu和ALU。
1. module ALU(
2. input wire[15:0] in1,
3. input wire[15:0] in2,
4. input wire[3:0] alu_op,
5. output reg ban,
6. output reg[15:0] z
7. );
8. always @(*)
9. begin
10. case(alu_op)
11. 4'b0001: begin z<=in1+in2;ban<=0; end
12. 4'b0010: begin z<=in1-in2;ban<=0; end
13. 4'b0011: begin z<=in1&in2;ban<=0; end
14. 4'b0100: begin z<=in1|in2;ban<=0; end
15. 4'b0101: begin z<=in1<<in2;ban<=0; end
16. 4'b0110: begin z<=in1>>in2;ban<=0; end
17. 4'b0111: begin z<=0; ban<=0; end//cla
18. 4'b1000: begin z<=~in1; ban<=0; end//com
19. 4'b1001: begin z<={{in1[15]},in1[15:1]};ban<=0; end //shr
20. 4'b1010: begin z<={{in1[14:0]},in1[15]}; ban<=0; end//csl
21. 4'b1011: begin z<=in2;ban<=0; end
22. 4'b1100: ban<=in1[15]==1 ? 1 : 0;
23. 4'b1101: ban<=0;
24. // 4'b0111: z<={{6{imm[8]}},imm}+in1;
25. // 4'b1000: z<=out_data;
26. endcase
27. end
28. endmodule
CU
1. module CU(
2. input wire [3:0] opcode,
3. output reg p_wr_en,
4. output reg m_wr_en,
5. output reg a_wr_en,
6.
7. output reg stop,
8. output reg [3:0] alu_op
9. );
10. always@(opcode)begin
11. case(opcode)
12. 4'b0001: begin //cla
13. p_wr_en<=0;
14. stop<=0;
15. m_wr_en<=1;
16. a_wr_en<=1;
17. alu_op<=4'b0111;
18. end
19. 4'b0010: begin//com
20. p_wr_en<=0;
21. stop<=0;
22. m_wr_en<=1;
23. a_wr_en<=1;
24. alu_op<=4'b1000;
25. end
26. 4'b0011: begin //shr
27. p_wr_en<=0;
28. stop<=0;
29. m_wr_en<=1;
30. a_wr_en<=1;
31. alu_op<=4'b1001;
32. end
33. 4'b0100: begin //csl
34. p_wr_en<=0;
35. stop<=0;
36. m_wr_en<=1;
37. a_wr_en<=1;
38. alu_op<=4'b1010;
39. end
40. 4'b0101: begin //stp
41. p_wr_en<=0;
42. stop<=1;
43. m_wr_en<=1;
44. a_wr_en<=0;
45. alu_op<=4'b1101;
46. end
47. 4'b0110: begin //add
48. p_wr_en<=0;
49. stop<=0;
50. m_wr_en<=1;
51. a_wr_en<=1;
52. alu_op<=4'b0001;
53. end
54. 4'b0111: begin //sta
55. p_wr_en<=0;
56. stop<=0;
57. m_wr_en<=0;
58. a_wr_en<=0;
59. alu_op<=4'b1101;
60. end
61. 4'b1000: begin //lda
62. p_wr_en<=0;
63. stop<=0;
64. m_wr_en<=1;
65. a_wr_en<=1;
66. alu_op<=4'b1011;
67. end
68. 4'b1001: begin //jmp
69. p_wr_en<=1;
70. stop<=0;
71. m_wr_en<=1;
72. a_wr_en<=0;
73. alu_op<=4'b1101;
74. end
75. 4'b1010: begin //ban
76. p_wr_en<=1;
77. stop<=0;
78. m_wr_en<=1;
79. a_wr_en<=0;
80. alu_op<=4'b1100;
81. end
82. endcase
83. end
84. endmodule
二.Pc执行停机指令时是在任何一个时钟周期内都可以进行,这样会使jmp或ban指令出错,所以我将器更改为仅在时钟周期上沿时可以停机。
PC
1. module PC(
2. input clk,
3. input rst,
4. input stop,
5. input ban,
6. input p_wr_en,
7. input wire [12:0] jmp,
8. output reg [12:0] pc
9. );
10. reg state;
11. initial begin
12. pc=8'd0;
13. state=1;
14. end
15. always@(posedge clk) begin
16. if(stop==1)
17. state<=0;
18. if(rst==1)
19. pc<=0;
20. end
21. always@(posedge clk) begin
22. if(state==1)
23. pc<=pc+1'd1;
24. end
25. always@(negedge clk) begin
26. if(p_wr_en==1)
27. pc<=jmp-1;
28. if(ban==1)
29. pc<=pc+jmp-1;
30. end
31. endmodule
仿真结果:
合肥工业大学计组实验五相关推荐
- 合肥工业大学计组实验四
实验目的 通过设计并实现支持一条指令的CPU,理解和掌握CPU设计的基本原理和过程. 实验内容 设计和实现一个支持加法指令的单周期CPU.要求该加法指令(表示为add r1,r2,r3)格式约定如下: ...
- 合肥工业大学机器人技术实验五十六题
注:非原创,仅仅做了整理工作. //PlayerTeams.cpp130行到138行是PlayOn模式开球后拿球到决策 //把原来到soc注释,在后面添加代码;每次修改后构建之后才能看到效果 在 pl ...
- logisim计组实验五 CRC校验电路
文章目录 CRC(7,3)串行编码电路 CRC(21,16)并行编码电路 CRC(21,16)并行解码电路 CRC校验电路的logisim设计,有什么问题就提出来吧~ 电路文件已经托管至Github, ...
- 西电计组实验一 存储器实验
FPGA中LPM_ROM定制与读出实验 一.实验目的 1.掌握FPGA中lpm_ROM的设置,作为只读存储器ROM的工作特性和配置方法: 2.用文本编辑器编辑mif文件配置ROM,学习将程序代 ...
- 超前进位加法器实验报告_北科大第二次计组实验报告超前进位加法器.doc
北科大第二次计组实验报告超前进位加法器 北京科技大学 计算机与通信工程学院 实 验 报 告 实验名称: 超前进位加法器 学生姓名: 专 业: 计算机科学与技术 班 级: 学 号: 指导教师: 实验成绩 ...
- 超前进位加法器实验报告_北科大第二次计组实验报告超前进位加法器
北科大第二次计组实验报告超前进位加法器 北京科技大学 计算机与通信工程学院实 验 报 告实验名称: 超前进位加法器 学生姓名: 专 业: 计算机科学与技术 班 级: 学 号: 指导教师: 实验成绩: ...
- 编译原理上机实习c语言小子集编译程序的实现报告,合肥工业大学编译原理实验报告(完整代码版)...
<合肥工业大学编译原理实验报告(完整代码版)>由会员分享,可在线阅读,更多相关<合肥工业大学编译原理实验报告(完整代码版)(58页珍藏版)>请在人人文库网上搜索. 1.计算机与 ...
- 计算机组成实验六MIPS汇编器,杭电计组实验6-MIPS汇编器与模拟器实验.doc
<杭电计组实验6-MIPS汇编器与模拟器实验.doc>由会员分享,提供在线免费全文阅读可下载,此文档格式为doc,更多相关<杭电计组实验6-MIPS汇编器与模拟器实验.doc> ...
- 计算机组成原理fc和fz,合肥工业大学计算机组成原理实验报告(DOC)
合肥工业大学计算机组成原理实验报告(DOC),合肥工业大学计算机组成原理,合肥工业大学计算机组成原理试卷,计算机组成原理实验pdf,计算机组成原理微程序,计算机组成原理实验报告,计算机组成原理知识点, ...
最新文章
- 魔与道的反复较量 反垃圾邮件技术
- [C#基础知识系列]专题十:全面解析可空类型
- 也许开发需要的只是一份简单明了的表格
- 【笔记】An explainable deep machine vision framework for plant stress phenotyping
- Handler 基本用法--线程间传值
- python基础(part4)--语句
- 数据库单表千万行 LIKE 搜索优化手记
- 将一个数组拼接成一个指定字符串返回
- 常见的mysql集群
- 【纯干货】4年前想解决的事情,今天才实验成功
- Sqlserver自动优化
- 亮风台AR眼镜震撼发布 HiAR 产品全面升级
- ppt模板免费下载的网站有哪些?这个宝藏网站必须make
- 分享5个国外较好的图片网站
- java.lang.reflect.Field常用方法
- assets文件使用
- Blackhat2017:如何利用PostScript语言入侵打印机
- 数据库原理 封锁的粒度
- MobileNetV2: Inverted Residuals and Linear Bottlenecks论文解读
- DSP28335 CAN模块例程