设计介绍:
这里就是在控制单元的输入口加入一个使能信号en,当这个en为0的时候,基于控制单元的各个子模块的使能信号为0,而当en为1的时候,其输出使能信号为1。
其代码修改部分为:
proc_controlunit.VHD中
当使能en为0的时候,指令状态在STATE_RESET上,就是系统暂停复位。
系统仿真介绍:
如仿真所示,当en为1的时候,系统各个模块的使能变高,系统开始工作,当en为低电平的时候,那么各个模块的使能信号为0,那么这个时候整个系统就没有工作。
为了设计控制单元,本任务需要设计一个基本的寄存器操作,本课题需要对控制系统设计的几个指令操作。
设计介绍:
指令说明,
LDI(Rd<-K):0100_KKKK_KKKK_dddd(注意,这里K为常数,d为目标寄存器地址)
MOV(Rd<-Rr):0000_0100_rrrr_dddd(注意,这里r为源地址,d为目标寄存器地址)
SSR(SEG[b] <-1): 0000_0000_0010_1bbb,
NOP:0000_0000_0000_0000
当执行LDI指令的时候,常数K要赋值给immediate_value,dddd赋值给
register_p_1_addr_direct。
当执行MOV指令的时候,rrrr赋值给register_p_0_addr_direct,dddd赋值给
register_p_1_addr_direct。
当执行SSR指令的时候,bbb赋值给sreg_bit_index。
当执行NOP的时候,就是16个0。
其设计代码如下所示:
当控制器接收到这几个指令的时候,控制器就会做出每个指令对应的操作。具体见下个部分的仿真效果。
系统仿真介绍:
从上面的仿真可以看到,当输入的指令为LDI,MOV,SSR,NOP时,控制器分别输出不同的控制信号。
为了设计控制单元,本任务需要设计一个基本的算术指令操作,本课题需要对控制系统设计几个指令操作。具体见下面的部分。
ANDI(Rd<-Rd+K):1010_KKKK_KKKK_dddd,K赋值给immediate_value,dddd赋值
给register_p_1_addr_direct。
AND(Rd←Rd and Rr):0000_0101_rrrr_dddd,rrrr赋值给register_p_0_addr_direct,dddd赋值给register_p_1_addr_direct。
ORI(Rd←Rd or K):1000_KKKK_KKKK_dddd,K赋值给immediate_value,dddd赋值
给register_p_1_addr_direct。
OR(Rd←Rd or Rr): 0000_0110_rrrr_dddd,rrrr赋值给register_p_0_addr_direct,dddd赋值给register_p_1_addr_direct。
EORI(Rd←Rd xor K):1001_KKKK_KKKK_dddd,K赋值给immediate_value,dddd赋值
给register_p_1_addr_direct。
EOR(Rd←Rd xor Rr): 0000_0111_rrrr_dddd,rrrr赋值给register_p_0_addr_direct,dddd赋值给register_p_1_addr_direct。
ADDI(Rd←Rd + K):1010_KKKK_KKKK_dddd,K赋值给immediate_value,dddd赋值
给register_p_1_addr_direct。
ADD(Rd←Rd + Rr):0000_1000_rrrr_dddd,rrrr赋值给register_p_0_addr_direct,dddd赋值给register_p_1_addr_direct。
ADC(Rd←Rd + Rr + C):0000_1001_rrrr_dddd,rrrr赋值给register_p_0_addr_direct,dddd赋值给register_p_1_addr_direct。
SUBI(Rd←Rd - K - C):1011_KKKK_KKKK_dddd,K赋值给immediate_value,dddd赋值
给register_p_1_addr_direct。
SUB(Rd←Rd - Rr):0000_1010_rrrr_dddd,rrrr赋值给register_p_0_addr_direct,dddd赋值给register_p_1_addr_direct。
SUBC(Rd←Rd - Rr - C): 0000_1011_rrrr_dddd,rrrr赋值给register_p_0_addr_direct,dddd赋值给register_p_1_addr_direct。
NEG(Rd ← not(Rd) + 1): 0000_0000_0001_dddd。dddd赋值给register_p_1_addr_direct。
COM(Rd ← not Rd): 0000_0000_0011_dddd。dddd赋值给register_p_1_addr_direct。
LSL(Rd ← Rd[6:0] & '0'):0000_0000_0100_dddd。dddd赋值给register_p_1_addr_direct。
LSR(Rd ← '0' & Rd[7:1]):0000_0000_0101_dddd。dddd赋值给register_p_1_addr_direct。
ROL(Rd ← Rd[6:0] & C):0000_0000_0110_dddd。dddd赋值给register_p_1_addr_direct。
ROR(Rd ← C & Rd[7:1]):0000_0000_0111_dddd。dddd赋值给register_p_1_addr_direct。
ASL(Rd ← Rd[6:0] & '0'):0000_0000_1000_dddd。dddd赋值给register_p_1_addr_direct。
ASR(Rd ← Rd[7] & Rd[7:1]):0000_0000_1001_dddd。dddd赋值给register_p_1_addr_direct。
CPI(Rd - K):0010_KKKK_KKKK_Dddd。
CP(Rd - Rr):0000_0001_rrrr_dddd。
这里涉及到的指令比较多,这里就不做进一步的介绍了。
这个是AND和ANDI运算,每个指令的设计VHDL代码均类似。我们以控制器输出AND指令为例子,其仿真代码如下所示:
JMP(PC←K):0001_KKKK_KKKK_0000;
RJMP(PC←PC + K + 1):0001_KKKK_KKKK_0001;
IJMP(PC←Rr):0001_0000_rrrr_0010
BRSS(PC←PC + K + 1):0011_KKKK_KKKK_1bbb。
BRSC(PC←PC + K + 1):0011_KKKK_KKKK_0bbb。
这里这些指令是针对事programmer counter的。
其对应的VHDL代码为:
其仿真原理和前面的相同。
本系统主要是将老师提供的netlist形式的ALU代码重新设计,设计为VHDL的ALU模块。主要通过指令输入,通过case语句进行设计。
本模块主要涉及如下几个指令:
ALU_ONESCOMP
ALU_TWOSCOMP
ALU_ADD_MODE
ALU_ADD_WC_MODE
ALU_SUB_MODE
ALU_SUB_WC_MODE
ALU_OR_MODE
ALU_AND_MODE
ALU_XOR_MODE
ALU_LOGICAL_LEFT
ALU_LOGICAL_RIGHT
ALU_ROTATE_LEFT
ALU_ROTATE_RIGHT
ALU_ARTHMETIC_LEFT
ALU_ARTHMETIC_RIGHT
其余指令可以用相同的方法进行扩展。
针对每个指令,分别计算其结果和status的值。
这个模块涉及到status寄存器状态的变换,status的值根据课题任务书的ALU部分的介绍即可。(注意,这里Status的运算,请仔细核对任务书上的计算方法)
A02-42