第一章 模型机基本结构
由功能分析, 本次组成原理实验中设计的模型机包含下面这些部件:算术逻辑运算部件(ALU)、程序计数器(PC)、指令寄存器(IR)、存储器(RAM)、时序和微程序控制部件。模型机的数据通路为单总线结构,总线宽度为8位。
第二章 设计思想
1、基于状态机的模型机
如图1所示,整体模型机的设计采用了状态机的思想,将cpu的取指令、指令译码、指令执行所对应的操作拆分到各个状态中,并由此设计模型机的微操作。
图1 - 时钟控制信号状态机模型示意图
2、周期、节拍、脉冲制
如图2所示,模型机的控制信号采用周期-节拍-脉冲制,机器周期由七个时钟节拍完成,且每个时钟节拍有两个打入脉冲clk进行驱动。
图2 - 时序、控制信号设计图
时序控制信号设计图中外部输入时钟为clk,本次模型机试验中将其与按键KEY[1]绑定作为模型机的时钟输入,整个设计图中的信号分别由时钟上升沿驱动控制,如clk_ctl、clk_pc、clk_ram、clk_ir、clk_alu,以及电平触发控制,如pc_inc、pc_out、ram_we、ram_rd、ir_in、ir_out、alu_in、alu_out组成。为满足时序电路的最小时序原则,在设计中电平变化时钟比时钟变化提前半个节拍一保证数据的正常传输。
3、模型机逻辑框图
如图3所示,模型机采用单总线的数据通路设计,模型机的整体结构分为:指令寄存器(pc)、程序寄存器(ir)、微程序控制器、算数运算单元(ALU)、时钟发生器、存储器(RAM),将各个部件按照图3所示分别连接到总线(BUS),内部数据通路流动方向如图所示,且部件中加入了寄存器和三态门的设计,因此可直接与总线相连。
图3 - 模型机逻辑框图
4、代码段数据段分离
模型机采用程序存储原理,如图4所示将代码段和数据段分离,在RAM中进行分段存储,便于指令的执行和数据的读取。
图4 – 内存存储示意图
5、指令格式
模型机总线宽度为8位,故模型机指令格式的设计为16位:高8位为指令操作码,分别为HLT、ADD、SUB、MUL、DIV;低8位为操作数在内存中的地址,采用单地址指令格式,下一字节即为双操作数中的第二操作数在内存中的地址。
图5 – 指令格式
6、顶层设计文件
如图6所示,模型机的顶层设计文件由以下几个部件构成:my_pc、my_clk、my_ram、my_ctl、my_ir、my_alu,且内部加入了寄存器和三态门,因此可以直接与总线相连,并通过控制信号控制各个部件之间的数据流动。
图6 - Micro Cpu顶层文件设计图
第三章 部分代码
整个工程代码我已上传至csdn-->基于模型机的Micro cpu设计
下载链接:http://download.csdn.net/detail/karma_w/8235475
1、存储器(RAM)
1 module my_ram 2 #(parameter DATA_WIDTH=8, parameter ADDR_WIDTH=8) 3 ( 4 input clk,we,rd, 5 input [(DATA_WIDTH-1):0] data, 6 input [(ADDR_WIDTH-1):0] addr, 7 output [(DATA_WIDTH-1):0] q 8 ); 9 10 // Declare the RAM variable 11 reg [DATA_WIDTH-1:0] ram[2**ADDR_WIDTH-1:0]; 12 reg state; 13 14 // Variable to hold the registered read address 15 reg [ADDR_WIDTH-1:0] addr_reg; 16 initial 17 begin 18 ram[1] <= 8‘b0000_0010; 19 ram[2] <= 8‘b0000_1000; 20 ram[8] <= 8‘b0000_0010; 21 ram[9] <= 8‘b0000_0100; 22 end 23 always @ (posedge clk) 24 begin 25 case (state) 26 1‘b0 : if(we) 27 begin 28 addr_reg <= addr; 29 state <= 1; 30 end 31 else 32 state <= 0; 33 1‘b1 : begin 34 addr_reg <= addr_reg + 1; 35 state <= 0; 36 end 37 38 default: state <= 0; 39 endcase 40 end 41 42 // Continuous assignment implies read returns NEW data. 43 // This is the natural behavior of the TriMatrix memory 44 // blocks in Single Port mode. 45 assign q = (rd)?ram[addr_reg]:8‘bz; 46 47 endmodule
2、逻辑运算器(ALU)
1 module my_alu 2 ( 3 input rst,clk,we,rd, 4 input [2:0] opcode, 5 input [7:0] alu_a,alu_b, 6 output [7:0] alu_out 7 ); 8 9 reg [7:0] alu_reg,alu_ac,alu_dr; 10 reg [1:0] state; 11 12 assign alu_out = rd?alu_reg:8‘bzzzz_zzzz; 13 14 always @(posedge clk or negedge rst) 15 if(!rst) 16 begin 17 alu_ac <= 0; 18 alu_dr <= 0; 19 alu_reg <= 0; 20 state <= 0; 21 end 22 else if(we) 23 case (state) 24 2‘b00 : begin 25 alu_ac <= alu_a; 26 state <= 01; 27 end 28 2‘b01 : begin 29 alu_dr <= alu_b; 30 state <= 10; 31 end 32 2‘b10 : begin 33 case (opcode) 34 3‘b000 : alu_reg<=alu_ac & alu_dr; //ANDD 35 3‘b001 : alu_reg<=alu_ac ^ alu_dr; //XORR 36 3‘b010 : alu_reg<=alu_ac + alu_dr; //ADD 37 3‘b011 : alu_reg<=alu_ac - alu_dr; //SUB 38 3‘b100 : alu_reg<=alu_ac * alu_dr; //MUL 39 3‘b101 : alu_reg<=alu_ac / alu_dr; //DIV 40 default:alu_reg<=8‘b0; 41 endcase 42 state <= 00; 43 end 44 default : state <= 00; 45 endcase 46 else 47 state <= 00; 48 endmodule
3、时序控制部件(CLK)
1 module my_clk 2 ( 3 input rst,clk, 4 output clk_ctl, 5 output reg clk_pc,clk_ir,clk_ram,clk_alu 6 ); 7 reg [3:0] state; 8 9 assign clk_ctl = ~clk; //clk_ctl-->clk_flip 10 always @(posedge clk or negedge rst) 11 if(!rst) 12 begin 13 clk_pc <= 0; 14 clk_ir <= 0; 15 clk_ram <= 0; 16 clk_alu <= 0; 17 state <= 0; 18 end 19 else 20 case (state) 21 4‘b0000 : begin 22 clk_pc <= clk_pc; 23 clk_ir <= clk_ir; 24 clk_ram <= clk_ram; 25 clk_alu <= clk_alu; 26 state <= 4‘b0001; 27 end 28 4‘b0001 : begin 29 clk_pc <= clk_pc; 30 clk_ir <= clk_ir; 31 clk_ram <= ~clk_ram; 32 clk_alu <= clk_alu; 33 state <= 4‘b0010; 34 end 35 4‘b0010 : begin 36 clk_pc <= clk_pc; 37 clk_ir <= clk_ir; 38 clk_ram <= ~clk_ram; 39 clk_alu <= clk_alu; 40 state <= 4‘b0011; 41 end 42 4‘b0011 : begin 43 clk_pc <= clk_pc; 44 clk_ir <= ~clk_ir; 45 clk_ram <= clk_ram; 46 clk_alu <= clk_alu; 47 state <= 4‘b0100; 48 end 49 4‘b0100 : begin 50 clk_pc <= clk_pc; 51 clk_ir <= ~clk_ir; 52 clk_ram <= ~clk_ram; 53 clk_alu <= clk_alu; 54 state <= 4‘b0101; 55 end 56 4‘b0101 : begin 57 clk_pc <= clk_pc; 58 clk_ir <= ~clk_ir; 59 clk_ram <= ~clk_ram; 60 clk_alu <= clk_alu; 61 state <= 4‘b0110; 62 end 63 4‘b0110 : begin 64 clk_pc <= clk_pc; 65 clk_ir <= ~clk_ir; 66 clk_ram <= clk_ram; 67 clk_alu <= clk_alu; 68 state <= 4‘b0111; 69 end 70 4‘b0111 : begin 71 clk_pc <= ~clk_pc; 72 clk_ir <= clk_ir; 73 clk_ram <= ~clk_ram; 74 clk_alu <= clk_alu; 75 state <= 4‘b1000; 76 end 77 4‘b1000 : begin 78 clk_pc <= ~clk_pc; 79 clk_ir <= clk_ir; 80 clk_ram <= ~clk_ram; 81 clk_alu <= clk_alu; 82 state <= 4‘b1001; 83 end 84 4‘b1001 : begin 85 clk_pc <= clk_pc; 86 clk_ir <= clk_ir; 87 clk_ram <= clk_ram; 88 clk_alu <= ~clk_alu; 89 state <= 4‘b1010; 90 end 91 4‘b1010 : begin 92 clk_pc <= clk_pc; 93 clk_ir <= clk_ir; 94 clk_ram <= ~clk_ram; 95 clk_alu <= ~clk_alu; 96 state <= 4‘b1011; 97 end 98 4‘b1011 : begin 99 clk_pc <= clk_pc; 100 clk_ir <= clk_ir; 101 clk_ram <= ~clk_ram; 102 clk_alu <= ~clk_alu; 103 state <= 4‘b1100; 104 end 105 4‘b1100 : begin 106 clk_pc <= clk_pc; 107 clk_ir <= clk_ir; 108 clk_ram <= clk_ram; 109 clk_alu <= ~clk_alu; 110 state <= 4‘b1101; 111 end 112 4‘b1101 : begin 113 clk_pc <= clk_pc; 114 clk_ir <= clk_ir; 115 clk_ram <= clk_ram; 116 clk_alu <= ~clk_alu; 117 state <= 4‘b1110; 118 end 119 4‘b1110 : begin 120 clk_pc <= clk_pc; 121 clk_ir <= clk_ir; 122 clk_ram <= clk_ram; 123 clk_alu <= ~clk_alu; 124 state <= 4‘b0000; 125 end 126 default : state <= 0; 127 endcase 128 endmodule