组合电路的部分只要根据功能和给定的端口进行设计即可。需要注意的主要是
1.避免生成latch锁存器,如果编译后提示电路存在锁存器,就需要检查代码消除锁存器。
2.不要轻易使用高阻态,高阻态的概念在实现前期部件时可能未学习,前面的几个部件通常不 会产生这个问题,后面遇到这个问题还会具体说明高阻态什么时候使用。
组合电路可以使用always语句也可以使用assign语句实现。使用两种语句生成电路的资源消耗和最大延迟可能不同,可尝试两种不同的写法进行比较,这也会影响最终实现模型机的性能。
1.功能
使能en有效为1时,将指令编码ir转换为指令信号发出,对应的指令信号输出为1。
2.指令编码表
3.代码
always语句是不断执行的,所以每次开始都将所有信号赋为0,根据编码判断哪个指令输出信号为1。指令表有三个MOV指令,分别定义为MOVA,MOVB,MOVC。
module instruction_decoder(EN,ir,MOVA,MOVB,MOVC,ADD,SUB,AND1,NOT1,RSR,RSL,JMP,JZ,JC, IN1,OUT1,NOP,HALT);
input [7:0] ir;
input EN;
output MOVA,MOVB,MOVC,ADD,SUB,AND1,NOT1,RSR,RSL,JMP,JZ,JC,IN1,OUT1,NOP,HALT;
reg MOVA,MOVB,MOVC,ADD,SUB,AND1,NOT1,RSR,RSL,JMP,JZ,JC,IN1,OUT1,NOP,HALT;
always@(ir,EN)
begin
MOVA=0;MOVB=0;MOVC=0;ADD=0;SUB=0;AND1=0;NOT1=0;RSR=0;RSL=0;JMP=0;JZ=0;JC=0;IN1=0; OUT1=0;NOP=0;HALT=0;
if (EN)
begin
if(ir[7:4]==4'b1100)
begin
if(ir[3]&ir[2]) MOVB=1;
else if(ir[1]&ir[0]) MOVC=1;
else MOVA=1'b1;
end
else if(ir[7:4]==4'b1001) ADD=1;
else if(ir[7:4]==4'b0110) SUB=1;
else if(ir[7:4]==4'b1011) AND1=1;
else if(ir[7:4]==4'b0101) NOT1=1;
else if(ir[7:4]==4'b1010)
begin
if(~ir[1]&~ir[0]) RSR=1;
else RSL=1;
end
else if(ir[7:4]==4'b0011)
begin
JC=ir[1];
JZ=ir[0];
JMP=!ir[1]&&!ir[0];
end
else if(ir[7:4]==4'b0010)IN1=1;
else if(ir[7:4]==4'b0100)OUT1=1;
else if(ir[7:4]==4'b0111)NOP=1;
else if(ir[7:4]==4'b1000) HALT=1;
else ;
end
else ;
end
endmodule
assign语句的写法,以MOV指令为例,其他指令类似。
...
assign MOVA=ir[7]&&ir[6]&&!ir[5]&&ir![4]&&!MOVB&&!MOVC //1100MOV指令且非MOVB,MOVC
assign MOVB=ir[7]&&ir[6]&&!ir[5]&&ir![4]&&ir[3]&&ir[2]; //110011XX
assign MOVC=ir[7]&&ir[6]&&!ir[5]&&ir![4]&&ir[1]&&ir[0]; //1100XX11
...
1.功能
m和s为运算控制信号,a和b为数据输入,cf,zf为状态输出,t为数据输出。
注意函数发生器的位置和端口,a,b接入的就是通用寄存器S和D的输出;t将结果输出给移位逻辑;s3-s0根据功能表,实际上就是指令编码的前四位;m由控制信号发生器发出;cf和zf的结果会给到状态寄存器。
2.代码
module ALU(a,b,s,m,t,cf,zf);
input [7:0] a;
input [7:0] b;
input m;
input [3:0] s;
output cf,zf;
output [7:0] t;
reg cf,zf;
reg [7:0] t;
always@(m,s,a,b)
begin
t=8'b0;
cf=1'b0;
zf=1'b0;
if(m==1)
begin
if(s==4'b1001)
begin
{cf,t}=a+b;
if(t==0) zf=1;
else zf=1'b0;
end
else if(s==4'b0110)
begin
{cf,t}=b-a;
if(t==0) zf=1'b1;
else zf=0;
end
else if(s==4'b1011) t=a&b;
else if(s==4'b0101) t=~b;
else if(s==4'b1010 || s==4'b0100) t=b;
else t=a;
end
else t=a;
end
endmodule
指令译码器和ALU比较简单,后面几个部件会重点放在几个容易犯错和需要注意的地方。