状态控制器由两部分组成:1.状态机(machine)。2.状态控制器(machinectl)。
状态控制器接收复位信号,当rst有效时,通过信号ena使其为0,输入到状态机中停止状态机的工作。verilog程序如下:
module machinectl(
input fetch,
input rst,
output reg ena
);
always @(posedge fetch or posedge rst)
begin
if(rst)
ena <= 0;
else
ena <= 1;
end
endmodule
状态机是cpu的控制核心,用于产生一系列的控制信号、启动或停止某些部件。cpu何时进行读指令读写io口、ram等,都由状态机来控制。
指令周期由8个时钟组成。
1.第0个时钟,cpu状态控制器的输出rd和load_ir为高电平,其余低电平。指令寄存器寄存rom送来的高8位指令代码。
2.第1个时钟,inc_pc从0变为1,故pc加1,rd和load_ir高电平,rom送来低8位指令。
3.第2个时钟,空操作。
4.第3个时钟,pc加1,指向下一条指令。若操作符为hlt,则输出信号hlt为高。
5.第4个时钟,若操作符为and、add、xor或lda,读相应地址的数据;若为jmp,将目的地址送给程序计数器;若为sto,输出累加器数据。
6.第5个时钟,若操作符为and、add或xor,算术运算器进行相应的运算;若为lda,就把数据通过算术运算器送给累加器;若为skz,先判断累加器的值是否为0,若为0,pc加1,否则不变;若为jmp,锁存目的地址;若为sto,将数据写入地址处。
7.第6个时钟,空操作。
8.第7个时钟,若操作符为skz且累加器值为0,pc加1,跳过一条指令,否则pc不变。
状态机verilog程序如下:
module machine(
input clk,
input zero,
input ena,
input [2:0] opcode,
input int_flag,
output reg inc_pc,
output reg load_acc,
output reg load_pc,
output reg rd,
output reg wr,
output reg load_ir,
output reg halt,
output reg datactl_ena
);
reg[2:0] state;
parameter HLT = 3'b000,
SKZ = 3'b001,
ADD = 3'b010,
ANDD = 3'b011,
XORR = 3'b100,
LDA = 3'b101,
STO = 3'b110,
JMP = 3'b111;
always @(negedge clk)
begin
if(!ena)
begin
state <= HLT;
{inc_pc,load_acc,load_pc,rd} <= 4'b0000;
{wr,load_ir,datactl_ena,halt} <= 4'b0000;
end
else
ctl_cycle;
end
task ctl_cycle;
begin
casex(state)
3'b000: begin //load high 8bits instruction
{inc_pc,load_acc,load_pc,rd} <= 4'b0001;
{wr,load_ir,datactl_ena,halt} <= 4'b0100;
state <= 3'b001;
end
3'b001: begin //pc increased by one then load low 8bits instruction
{inc_pc,load_acc,load_pc,rd} <= 4'b1001;
{wr,load_ir,datactl_ena,halt} <= 4'b0100;
state <= 3'b010;
end
3'b010: begin //idle
{inc_pc,load_acc,load_pc,rd} <= 4'b0000;
{wr,load_ir,datactl_ena,halt} <= 4'b0000;
state <= 3'b011;
end
3'b011: begin //next instruction address setup 分析指令
if(opcode == HLT)
begin
{inc_pc,load_acc,load_pc,rd} <= 4'b1000;
{wr,load_ir,datactl_ena,halt} <= 4'b0001;
end
else begin
{inc_pc,load_acc,load_pc,rd} <= 4'b1000;
{wr,load_ir,datactl_ena,halt} <= 4'b0000;
end
state <= 3'b100;
end
3'b100: begin //fetch oprand
if(opcode == JMP)
begin
{inc_pc,load_acc,load_pc,rd} <= 4'b0010;
{wr,load_ir,datactl_ena,halt} <= 4'b0000;
end
else
if(opcode==ADD || opcode==ANDD || opcode==XORR || opcode==LDA)
begin
{inc_pc,load_acc,load_pc,rd} <= 4'b0001;
{wr,load_ir,datactl_ena,halt} <= 4'b0000;
end
else
if(opcode == STO)
begin
{inc_pc,load_acc,load_pc,rd} <= 4'b0000;
{wr,load_ir,datactl_ena,halt} <= 4'b0010;
end
else
begin
{inc_pc,load_acc,load_pc,rd} <= 4'b0000;
{wr,load_ir,datactl_ena,halt} <= 4'b0000;
end
state <= 3'b101;
end
3'b101: begin //operation
if(opcode==ADD || opcode==ANDD || opcode==XORR || opcode==LDA)
begin
{inc_pc,load_acc,load_pc,rd} <= 4'b0101;
{wr,load_ir,datactl_ena,halt} <= 4'b0000;
end
else
if(opcode==SKZ && zero==1)
begin
{inc_pc,load_acc,load_pc,rd} <= 4'b1000;
{wr,load_ir,datactl_ena,halt} <= 4'b0000;
end
else
if(opcode == JMP)
begin
{inc_pc,load_acc,load_pc,rd} <= 4'b1010;
{wr,load_ir,datactl_ena,halt} <= 4'b0000;
end
else
if(opcode == STO)
begin
{inc_pc,load_acc,load_pc,rd} <= 4'b0000;
{wr,load_ir,datactl_ena,halt} <= 4'b1010;
end
else
begin
{inc_pc,load_acc,load_pc,rd} <= 4'b0000;
{wr,load_ir,datactl_ena,halt} <= 4'b0000;
end
state <= 3'b110;
end
3'b110: begin //idle
if(opcode == STO)
begin
{inc_pc,load_acc,load_pc,rd} <= 4'b0000;
{wr,load_ir,datactl_ena,halt} <= 4'b0010;
end
else
if(opcode==ADD || opcode==ANDD || opcode==XORR || opcode==LDA)
begin
{inc_pc,load_acc,load_pc,rd} <= 4'b0001;
{wr,load_ir,datactl_ena,halt} <= 4'b0000;
end
else
begin
{inc_pc,load_acc,load_pc,rd} <= 4'b0000;
{wr,load_ir,datactl_ena,halt} <= 4'b0000;
end
state <= 3'b111;
end
3'b111: begin //
if(opcode==SKZ && zero==1)
begin
{inc_pc,load_acc,load_pc,rd} <= 4'b1000;
{wr,load_ir,datactl_ena,halt} <= 4'b0000;
end
else
begin
{inc_pc,load_acc,load_pc,rd} <= 4'b0000;
{wr,load_ir,datactl_ena,halt} <= 4'b0000;
end
state <= 3'b000;
end
default: begin
{inc_pc,load_acc,load_pc,rd} <= 4'b0000;
{wr,load_ir,datactl_ena,halt} <= 4'b0000;
state <= 3'b000;
end
endcase
end
endtask
endmodule
整体模块图如下:
文章评论(0条评论)
登录后参与讨论