模型机设计(VERILOG)-指令译码器与ALU

前言

        组合电路的部分只要根据功能和给定的端口进行设计即可。需要注意的主要是
        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
    ...

4.功能仿真
        验证各个指令信号是否能正确输出。
        

二.ALU

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

3.功能仿真
        逐个指令进行功能验证,输出正确即可。

        指令译码器和ALU比较简单,后面几个部件会重点放在几个容易犯错和需要注意的地方。
 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值