|
五.各个部件的代码实现
1.PC部件的代码实现
module pc (clock,reset,en,pc);
input clock, reset, en;
output reg [4:0] pc;
wire [4:0] pc_next; //欲寻址的下一条指令
//always过程快
always@ (posedge clock or posedge reset)
begin
if(reset) //系统复位,pc清0
pc <= 0;
else
if(en) //如果使能pc模块,则将下一条指令付给pc端口输出
pc <= pc_next;
else
pc <= pc; //否则,pc保持即不工作
end
//assign持续赋值语句
assign pc_next = pc + 1; //本处理器中下一条指令的地址为当前地址加1
endmodule
2.存储器(Memory)的代码实现
module memory (clock,reset,addr,din,dout,wr,rd);
input clock; //时钟信号线
input reset; //复位信号,高电平有效
input [4:0] addr; //存储器地址
input [7:0] din; //数据线输入
output reg [7:0] dout; //数据线输出
input wr; //写使能端,高电平有效
input rd; //读使能端,高电平有效
reg [7:0] mem [0:31]; //内部的存储空间
always @(posedge clock or posedge reset) begin
if (reset) begin
mem [0] <= 'b00001011; //LDA 01011
mem [1] <= 'b01001100; //ADD 01100
mem [2] <= 'b00101101; //STA 01101
mem [3] <= 'b00001011; //LDA 01011
mem [4] <= 'b10001100; //AND 01100
mem [5] <= 'b00101110; //STA 01110
mem [6] <= 'b00001011; //LDA 01011
mem [7] <= 'b01101100; //SUB 01100
mem [8] <= 'b00101111; //STA 01111
mem [9] <= 'b10100000; //HLT
mem [10] <= 'b00000000;
mem [11] <= 'b10010101;
mem [12] <= 'b01100101;
mem [13] <= 'b00000000;
mem [14] <= 'b00000000;
mem [15] <= 'b00000000;
mem [16] <= 'b00000000;
mem [17] <= 'b00000000;
mem [18] <= 'b00000000;
mem [19] <= 'b00000000;
mem [20] <= 'b00000000;
mem [21] <= 'b00000000;
mem [22] <= 'b00000000;
mem [23] <= 'b00000000;
mem [24] <= 'b00000000;
mem [25] <= 'b00000000;
mem [26] <= 'b00000000;
mem [27] <= 'b00000000;
mem [28] <= 'b00000000;
mem [29] <= 'b00000000;
mem [30] <= 'b00000000;
mem [31] <= 'b00000000;
end
else begin
if (wr)
mem [addr] <= din;
if (rd)
dout <= mem [addr];
end
end
endmodule
3.指令解码器(Idec)的代码实现
module idec (
clock, //时钟端口
reset, //复位端口
en, //译码使能端口
instruction, //指令输入端口
opcode, //操作吗输入端口
addr, //存储器地址输入端口
);
input clock,reset,en;
input [7:0] instruction;
output reg [2:0] opcode;
output reg [4:0] addr;
always @(posedge clock or posedge reset) begin
if (reset) begin
opcode <= 0;
addr <= 0;
// reset
end
else if (en) begin
opcode <= instruction [7:5];
addr <= instruction [4:0];
end
end
endmodule
4.算术逻辑单元(ALU)的代码生成:
module alu (
clock, //时钟端口
reset, //复位端口
en, //alu使能端口
a, //累加器输出寄存器
din, //操作数1输入
n, //负标志
z, //0标志
c, //输出进位标志
v, //输出溢出标志
add_en, //加法使能运算
sub_en, //减法使能运算
and_en, //与运算
pass_en, //使din直通累加器A,不做运算(部分运算需要)
);
input clock,reset,en,add_en,sub_en,and_en,pass_en;
input [7:0] din;
output n,z,c,v;
output reg [7:0] a;
reg c;
always @(posedge clock or posedge reset)
if (reset) begin
a <= 0; //复位累加器清0,
c <= 0;
// reset
end
else begin
if(en) begin
if(add_en)
{c,a} <= a [7:0] + din;
else if(sub_en)
{c,a} <= a [7:0] - din;
else if(and_en)
a <= a & din;
else if(pass_en)
a <= din;
end
end
assign z = (a == 8'b0) ? 1: 0 ; //0标志,如果累加器为0,z=1
assign n = (c == 1) ? 1: 0 ; //负数标志,如果借位为1,则n=1
assign v = ((a>127) || (a<-128) ? 1:0 ); //溢出标志
endmodule
5.控制单元(Control)的代码实现:
module control (
input clock,
input reset, //异步复位端端口
output reg s0, //分别作用各阶段的使能信号个端口
output reg s1,
output reg s2,
output reg s3,
output reg s4,
output reg s5,
output reg addrsel, //选择程序的地址或者选择数据的地址
output reg instr_add, //加法端口使能信号,以下类似
output reg instr_sub,
output reg instr_and,
output reg instr_pass,
input [2:0] opcode //解码器解码后将指令码传给控制器
);
parameter [2:0] LDA = 3'b000, STA = 3'b001, ADD = 3'b010, SUB = 3'b011, AND = 3'b100 , HLT = 3'b101;
reg [2:0] cnt; //指令执行需要6个阶段,用cnt计数来表示不同的阶段
always @(posedge clock or posedge reset)
if (reset)
// reset
cnt <= 0;
else
if (cnt==5)
cnt <= 0;
else
cnt <= cnt+1;
always@ *
begin
case(cnt)
0: begin //取指
s0<=1; s1<=0; s2<=0; s3<=0; s4<=0; s5<=0;
addrsel<=0;
end
1:begin //解码
s0<=0; s1<=1; s2<=0; s3<=0; s4<=0; s5<=0;
addrsel<=0;
end
2:begin //根据操作码决定是否从存储器中读取数据
s0<=0; s1<=0; s2<=1; s3<=0; s4<=0; s5<=0;
addrsel<=1;
if( (opcode==LDA) ||
(opcode==ADD) ||
(opcode==SUB) ||
(opcode==AND) )
s2<=1;
else
s2<=0;
end
3:begin //确定ALU的运算
s0<=0; s1<=0; s2<=0; s3<=1; s4<=0; s5<=0;
addrsel<=1;
if (opcode==LDA) begin
instr_add<=0;
instr_sub<=0;
instr_and<=0;
instr_pass<=1;
end
else if(opcode==ADD) begin
instr_add<=1;
instr_sub<=0;
instr_and<=0;
instr_pass<=0;
end
else if(opcode==SUB) begin
instr_add<=0;
instr_sub<=1;
instr_and<=0;
instr_pass<=0;
end
else if(opcode==AND) begin
instr_add<=0;
instr_sub<=0;
instr_and<=1;
instr_pass<=0;
end
else if(opcode==STA) begin
instr_add<=0;
instr_sub<=0;
instr_and<=0;
instr_pass<=0;
end
else begin
instr_add<=0;
instr_sub<=0;
instr_and<=0;
instr_pass<=0;
end
end
4:begin //必要时往存储器中写数据
s0<=0; s1<=0; s2<=0; s3<=0; s4<=1; s5<=0;
addrsel<=1;
if(opcode==STA)
s4<=1;
else
s4<=0;
end
5:begin //使能PC准备开始读取下一条指令
s0<=0; s1<=0; s2<=0; s3<=0; s4<=0; s5<=1;
addrsel<=1;
end
endcase
end
endmodule
|
|