第八章 可综合的Verilog HDL设计实例
----------------------------------------------------------------------------------------------------------------------
8.2.8.状态控制器
CLK1CLK1ZEROZEROINC_PCLOAD_ACCLOAD_PCENARDINC_PCLOAD_ACCLOAD_PCMEM_RDMEM_WRLOAD_IRHALTDATACTL_ENAFETCHFETCH machinectlENARSTRSTMACHINEOPCODE[2:0]OPCODE[2:0]WRLOAD_IRHALTDATACTL_ENAINT_FLAGINT_FLAG
图8.2.8状态控制器
状态控制器由两部分组成:
状态机(上图中的MACHINE部分)
状态控制器(上图中的MACHINECTL部分)
状态机控制器接受复位信号RST,当RST有效时通过信号ena使其为0,输入到状态机中停止状态机的工作。
状态控制器的VerilogHDL程序见下面模块:
//------------------------------------------------------------------------------
module machinectl( ena, fetch, rst); output ena;
input fetch, rst; reg ena;
always @(posedge fetch or posedge rst) begin
if(rst) ena<=0; else
ena<=1; end
endmodule
//------------------------------------------------------------------------------
181
第八章 可综合的Verilog HDL设计实例
----------------------------------------------------------------------------------------------------------------------
状态机是CPU的控制核心,用于产生一系列的控制信号,启动或停止某些部件。CPU何时进行读指令读写I/O端口,RAM区等操作,都是由状态机来控制的。状态机的当前状态,由变量state记录,state的值就是当前这个指令周期中已经过的时钟数(从零计起)。
指令周期是由8个时钟周期组成,每个时钟周期都要完成固定的操作。
1) 第0个时钟,因为CPU状态控制器的输出:rd和load_ir为高电平,其余均为低电平。指令寄存器
寄存由ROM送来的高8位指令代码。
2) 第1个时钟,与上一时钟相比只是inc_pc从0变为1故PC增1,ROM送来低8位指令代码,指令寄存
器寄存该8位代码。
3) 第2个时钟,空操作。
4) 第3个时钟,PC增1,指向下一条指令。若操作符为HLT,则输出信号HLT为高。如果操作符不为
HLT,除了PC增一外(指向下一条指令),其它各控制线输出为零。
5) 第4个时钟,若操作符为AND、ADD、XOR或LDA,读相应地址的数据;若为JMP,将目的地址送给
程序计数器;若为STO,输出累加器数据。
6) 第5个时钟,若操作符为ANDD、ADD或XORR,算术运算器就进行相应的运算;若为LDA,就把数据
通过算术运算器送给累加器;若为SKZ,先判断累加器的值是否为0,如果为0,PC就增1,否则保持原值;若为JMP,锁存目的地址;若为STO,将数据写入地址处。
7) 第6个时钟,空操作。
8) 第7个时钟,若操作符为SKZ且累加器值为0,则PC值再增1,跳过一条指令,否则PC无变化。
状态机的VerilogHDL 程序见下面模块:
//------------------------------------------------------------------------------ module machine( inc_pc, load_acc, load_pc, rd,wr, load_ir,
datactl_ena, halt, clk1, zero, ena, opcode );
output inc_pc, load_acc, load_pc, rd, wr, load_ir; output datactl_ena, halt; input clk1, zero, ena; input [2:0] opcode;
reg inc_pc, load_acc, load_pc, rd, wr, load_ir; reg datactl_ena, halt; 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 clk1 )
182
第八章 可综合的Verilog HDL设计实例
----------------------------------------------------------------------------------------------------------------------
begin
if ( !ena ) //接收到复位信号RST,进行复位操作 begin
state<=3'b000;
{inc_pc,load_acc,load_pc,rd}<=4'b0000; {wr,load_ir,datactl_ena,halt}<=4'b0000; end else
ctl_cycle; end
//-----------------begin of task ctl_cycle---------
task ctl_cycle; begin
casex(state)
3’b000: //load high 8bits in struction
begin
{inc_pc,load_acc,load_pc,rd}<=4'b0001; {wr,load_ir,datactl_ena,halt}<=4'b0100; state<=3’b001; end
3’b001: //pc increased by one then load low 8bits instruction
begin
{inc_pc,load_acc,load_pc,rd}<=4'b1001; {wr,load_ir,datactl_ena,halt}<=4'b0100; state<=3’b010; end
3’b010: //idle
begin
{inc_pc,load_acc,load_pc,rd}<=4'b0000; {wr,load_ir,datactl_ena,halt}<=4'b0000; state<=3’b011; end
3’b011: //next instruction address setup 分析指令从这里开始
begin
if(opcode==HLT) //指令为暂停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: //fetch oprand
begin
if(opcode==JMP) begin
{inc_pc,load_acc,load_pc,rd}<=4'b0010;
183
第八章 可综合的Verilog HDL设计实例
----------------------------------------------------------------------------------------------------------------------
3’b101:
{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 //operation begin
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
//过一个时钟后把wr变1就可写到RAM中
{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;
184
第八章 可综合的Verilog HDL设计实例
----------------------------------------------------------------------------------------------------------------------
{wr,load_ir,datactl_ena,halt}<=4'b0000; end
state<=3’b110;
end 3’b110: //idle begin
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
//-----------------end of task ctl_cycle---------
endmodule
185