module hunch_fsm
(
input clk,
input rst, // active high reset
input A,B,C,
output [2:0] winner_disp, // display winner
output a_disp, // 0:sit, 1:stand
output b_disp,
output c_disp
);
/*
winner_disp 2 1 0
A 0 0 1
B 0 1 0
A,B 0 1 1
C 1 0 0
C,A 1 0 1
C,B 1 1 0
DRAW 1 1 1
*/
parameter S_INIT =4'b0000,
S_AS =4'b1001,
S_BS =4'b1010,
S_CS =4'b1100,
S_AW =4'b0001,
S_BW =4'b0010,
S_CW =4'b0100,
S_ABW=4'b0011,
S_ACW=4'b0101,
S_BCW=4'b0110,
S_DRAW=4'b0111;
reg [3:0] st,nst;
always @(posedge clk)
begin
if(rst==1'b1)
st<=S_INIT;
else
st <= nst;
end
always @(*)
begin
/* if(rst==1'b1)
nst<=S_INIT;
else
begin
*/
case(st)
S_INIT: begin
if({A,B,C}==3'b100)
nst = S_AS;
else if({A,B,C}==3'b010)
nst = S_BS;
else if({A,B,C}==3'b001)
nst = S_CS;
else if({A,B,C}==3'b011)
nst = S_AW;
else if({A,B,C}==3'b101)
nst = S_BW;
else if({A,B,C}==3'b110)
nst = S_CW;
else if({A,B,C}==3'b111)
nst = S_DRAW;
else
nst = S_INIT;
end
S_AS: begin
if({B,C}==2'b10)
nst = S_ABW;
else if({B,C}==2'b01)
nst = S_ACW;
else if({B,C}==2'b11)
nst = S_AW;
else
nst = S_AS;
end
S_BS: begin
if({A,C}==2'b10)
nst = S_ABW;
else if({A,C}==2'b01)
nst = S_BCW;
else if({A,C}==2'b11)
nst = S_BW;
else
nst = S_BS;
end
S_CS: begin
if({A,B}==2'b10)
nst = S_ACW;
else if({A,B}==2'b01)
nst = S_BCW;
else if({A,B}==2'b11)
nst = S_CW;
else
nst = S_CS;
end
S_AW:
nst = S_AW;
S_BW:
nst = S_BW;
S_CW:
nst = S_CW;
S_ABW:
nst = S_ABW;
S_ACW:
nst = S_ACW;
S_BCW:
nst = S_BCW;
S_DRAW:
nst = S_DRAW;
default:
nst = S_INIT;
endcase
// end
end
assign a_disp=(st==S_AW)|(st==S_ABW)|(st==S_ACW)|(st==S_DRAW);
assign b_disp=(st==S_BW)|(st==S_ABW)|(st==S_BCW)|(st==S_DRAW);
assign c_disp=(st==S_CW)|(st==S_ACW)|(st==S_BCW)|(st==S_DRAW);
assign winner_disp = {c_disp,b_disp,a_disp};
endmodule
`define SEED 32'h0000_0001
// +define+SEED=1
class ABC_c;
rand bit a,b,c;
rand bit a1,b1,c1;
static int i=0;
function void get_rVal();
if(i==0)
begin
{c1,b1,a1,c,b,a}=$random(`SEED);
i=i+1;
end
else
{c1,b1,a1,c,b,a}=$random();
endfunction
endclass
`timescale 1ns/1ns
module tb_hunch_fsm;
reg clk;
reg rst; // active high reset
reg A,B,C;
wire [2:0] winner_disp; // display winner
wire a_disp; // 0:sit, 1:stand
wire b_disp;
wire c_disp;
hunch_fsm DUT
(
.clk(clk),
.rst(rst), // active high reset
.A(A),.B(B),.C(C),
.winner_disp(winner_disp), // display winner
.a_disp(a_disp), // 0:sit, 1:stand
.b_disp(b_disp),
.c_disp(c_disp)
);
ABC_c test_c;
always #10 clk=~clk;
initial
begin
test_c = new();
clk=1'b0; rst=1'b1;A=1'b0; B=1'b0; C=1'b0;
#100 rst=1'b0;
end
always #20
begin
TRY;
test_c.get_rVal();
SELPerson (test_c.c,test_c.b,test_c.a );
SELPerson (test_c.c1,test_c.b1,test_c.a1);
end
task SELPerson
(
input c,b,a
);
begin
rst=1'b0;
A=a; B=b; C=c;
@(posedge clk);
end
endtask
task TRY;
begin
@(posedge clk);
rst=1'b1;
A=1'b0; B=1'b0; C=1'b0;
@(posedge clk);
end
endtask
endmodule
첫댓글 vlog -vlog01compat -work work +define+SEED=1 +incdir+E:/my_jae/hunch_fsm/.. {E:/my_jae/hunch_fsm/../tb_hunt_fsm.v}