LAB 7:利用有限状态机进行复杂时序逻辑的设计
一、 二、
实验目的 实验原理
掌握利用有限状态机(FSM)实现复杂时序逻辑的方法。
控制器是CPU的控制核心,用于产生一系列的控制信号,启动或停止某些部件。CPU何时进行读指令,何时进行RAM和I/O端口的读写操作等,都由控制器来控制。
三、 源代码
补充代码
nexstate<=state+1'h01;
case(state)
1:begin sel=1;rd=0;ld_ir=0;inc_pc=0;halt=0;ld_pc=0;data_e=0;ld_ac=0;wr=0;end 2:begin sel=1;rd=1;ld_ir=0;inc_pc=0;halt=0;ld_pc=0;data_e=0;ld_ac=0;wr=0;end 3:begin sel=1;rd=1;ld_ir=1;inc_pc=0;halt=0;ld_pc=0;data_e=0;ld_ac=0;wr=0;end 4:begin sel=1;rd=1;ld_ir=1;inc_pc=0;halt=0;ld_pc=0;data_e=0;ld_ac=0;wr=0;end 5:begin sel=0;rd=0;ld_ir=0;inc_pc=1;ld_pc=0;data_e=0;ld_ac=0;wr=0; if(opcode==`HLT) halt=1; end
6:begin sel=0;rd=alu_op;ld_ir=0;inc_pc=0;halt=0;ld_pc=0;data_e=0;ld_ac=0;wr=0;end 7:begin sel=0;rd=alu_op;ld_ir=0;halt=0;data_e=!alu_op;ld_ac=0;wr=0; if(opcode==`SKZ) inc_pc<=zero; if(opcode==`JMP) ld_pc=1; end 0:begin
sel=0;rd=alu_op;ld_ir=0;halt=0;data_e=!alu_op;ld_ac=alu_op;inc_pc=(opcode==`SKZ)&zero||(opcode==`JMP);
if(opcode==`JMP) ld_pc=1;
if(opcode==`STO) wr=1; end
//default:begin
sel=1'bZ;rd=1'bZ;ld_ir=1'bZ;inc_pc=1'bZ;halt=1'bZ;ld_pc=1'bZ;data_e=1'bZ;ld_ac=1'bZ;wr=1'bZ;end
endcase end
control_test.v
/*****************************
* TEST BENCH FOR CONTROLLER * *****************************/
`timescale 1 ns / 1 ns
module control_test ;
reg [8:0] response [0:127]; reg [3:0] stimulus [0:15]; reg [2:0] opcode; reg clk; reg rst_; reg zero; integer i,j;
reg[(3*8):1] mnemonic;
// Instantiate controller
control c1 ( rd , wr , ld_ir , ld_ac , ld_pc , inc_pc , halt , data_e , sel , opcode , zero , clk , rst_ );
// Define clock
initial begin clk = 1 ;
forever begin
#10 clk = 0 ; #10 clk = 1 ; end end
// Generate mnemonic for debugging purposes
always @ ( opcode ) begin
case ( opcode )
3'h0 : mnemonic = \ 3'h1 : mnemonic = \ 3'h2 : mnemonic = \ 3'h3 : mnemonic = \ 3'h4 : mnemonic = \ 3'h5 : mnemonic = \ 3'h6 : mnemonic = \ 3'h7 : mnemonic = \ default : mnemonic = \ endcase end
// Monitor signals initial begin
$timeformat ( -9, 1, \
$display ( \ time rd wr ld_ir ld_ac ld_pc inc_pc halt data_e sel opcode zero state\
$display ( \// $shm_open ( \// $shm_probe ( \// $shm_probe ( c1.state ) ; end
// Apply stimulus
initial begin
$readmemb ( \ rst_=1;
@ ( negedge clk ) rst_ = 0 ; @ ( negedge clk ) rst_ = 1 ; for ( i=0; i<=15; i=i+1 ) @ ( posedge ld_ir ) @ ( negedge clk )
{ opcode, zero } = stimulus[i] ; end
// Check response
initial begin
$readmemb ( \ @ ( posedge rst_ )
for ( j=0; j<=127; j=j+1 ) @ ( negedge clk ) begin
$display(\%b %b %b %b %b %b %b %b %b %b %b\
$time,rd,wr,ld_ir,ld_ac,ld_pc,inc_pc,halt,data_e,sel,opcode,zero,c1.state ) ;
if ( {rd,wr,ld_ir,ld_ac,ld_pc,inc_pc,halt,data_e,sel} !== response[j] ) begin : blk reg [8:0] r;
r = response[j];
$display ( \ $display
( \ %b %b %b %b %b %b %b %b\
$time,r[8],r[7],r[6],r[5],r[4],r[3],r[2],r[1],r[0] ) ; $display ( \ $stop;
$finish ; end end
$display ( \ $stop; $finish ; end
endmodule
%b