Kraklog
Day.83 Advanced Verilog #6 본문
728x90
module state_machine (
input clk, res,
input chn1, sync, valid,
output reg data_a, data_b, validate, error
);
`ifdef USER_EC
parameter
idle =5'b00000,
header_wait =5'b00010,
got_header =5'b00001,
a1 =5'b00100,
a2 =5'b00101,
a3 =5'b00110,
b1 =5'b01000,
b2 =5'b01001,
b3 =5'b01010,
recover =5'b10000;
reg [3:0] current_state, next_state;
`else
parameter
idle =5'b00000,
header_wait =5'b00010,
got_header =5'b00001,
a1 =5'b00100,
a2 =5'b00101,
a3 =5'b00110,
b1 =5'b01000,
b2 =5'b01001,
b3 =5'b01010,
recover =5'b10000;
reg [3:0] current_state, next_state;
`endif
always @ (posedge clk, posedge res)
begin: machine_transitions
if (res)
current_state <= idle;
else
current_state <= next_state;
end
always @ *
begin: next_state_decode
case (current_state)
idle: if (sync) next_state = header_wait;
else next_state = idle;
header_wait:
if (valid) next_state = got_header;
else next_state = header_wait;
got_header:
if (!chn1) next_state = a1;
else next_state = b1;
a1: next_state = a2;
b1: next_state = b2;
a2: next_state = a3;
b2: next_state = b3;
a3: if (valid) next_state = header_wait;
else next_state = recover;
b3: if (valid) next_state = header_wait;
else next_state = recover;
recover:
if (sync) next_state = header_wait;
else next_state = recover;
default:
next_state = idle;
endcase
end
always @ (current_state)
begin: machine_outputs
data_a = 1'b0;
data_b = 1'b0;
validate = 1'b0;
error = 1'b0;
case (current_state)
idle: ;
//0000
//EBAV
header_wait:
//0001
//EBAV
validate = 1'b1;
a1: data_a = 1'b1;
//0010
//EBAV
a2: data_a = 1'b1;
//0010
//EBAV
a3: begin
//0011
//EBAV
data_a = 1'b1;
validate = 1'b1;
end
//0100
//EBAV
b1: data_b = 1'b1;
//0100
//EBAV
b2: data_b = 1'b1;
//0101
//EBAV
b3: begin
data_b = 1'b1;
validate = 1'b1;
end
recover:
//1000
//EBAV
error = 1'b1;
default: ;
endcase
end
endmodule
module StateMachine (
input clk ,
input reset ,
input door_closed ,
input full ,
input heat_demand ,
input done ,
input empty ,
output reg water ,
output reg spin ,
output reg heat ,
output reg pump
);
reg [2:0] current_state, next_state;
parameter
idle = 0,
fill = 1,
heat_w = 2,
wash = 3,
drain = 4;
//reset
always @(posedge clk)
if(reset)
current_state <= idle;
else
current_state <= next_state;
always @ *
begin
next_state = current_state; //default logic
case(current_state)
fill :
if (full)
next_state = heat_w;
heat_w :
if (!heat_demand)
next_state = wash;
wash :
begin
if(heat_demand)
next_state = heat_w;
if(done)
next_state = drain;
end
drain :
if(empty)
next_state = idle;
default :
if(door_closed)
next_state = fill;
endcase
end
always @ *
begin
water = 0;
spin = 0;
heat = 0;
pump = 0;
case(next_state)
fill : begin
water = 1;
end
heat_w : begin
spin = 1;
heat = 1;
end
wash : begin
spin = 1;
end
drain : begin
spin = 1;
pump = 1;
end
default : ;
endcase
end
endmodule
`timescale 1ns/ 1ns
`define CLK_50Mhz 20
module tb_StateMachine ();
reg clk ;
reg reset ;
reg door_closed ;
reg full ;
reg heat_demand ;
reg done ;
reg empty ;
wire water ;
wire spin ;
wire heat ;
wire pump ;
StateMachine uStateMachine (
.clk (clk ) ,
.reset (reset ) ,
.door_closed(door_closed) ,
.full (full ) ,
.heat_demand(heat_demand) ,
.done (done ) ,
.empty (empty ) ,
.water (water ) ,
.spin (spin ) ,
.heat (heat ) ,
.pump (pump )
);
initial fork
clk_gen();
data_gen();
ctrl_gen();
reset_gen();
join
task clk_gen;
begin
clk = 1'b0;
forever #(`CLK_50Mhz/2) clk =~clk ;
end
endtask
task reset_gen;
begin
reset = 1'b0;
repeat(2) @(negedge clk);
reset = 1'b1;
repeat(2) @(negedge clk);
reset = 1'b0;
end
endtask
task data_gen;
begin
end
endtask
task ctrl_gen;
begin
door_closed = 1'b0;
full = 1'b0;
heat_demand = 1'b0;
done = 1'b0;
empty = 1'b0;
repeat(2) @(negedge clk);
door_closed = 1'b1;
repeat(3) @(negedge clk);
full = 1'b1;
repeat(3) @(negedge clk);
heat_demand = 1'b0;
repeat(5) @(negedge clk);
heat_demand = 1'b1;
repeat(5) @(negedge clk);
heat_demand = 1'b0;
repeat(2) @(negedge clk);
done = 1'b1;
repeat(3) @(negedge clk);
empty = 1'b1;
end
/*integer i;
begin
addr=0;
repeat(4) @(negedge clk);
for (i=0; i<32; i=i+1) begin
addr = addr +1;
@(negedge clk);
end
end*/
endtask
localparam [2:0] idle = 3'h0;
localparam [2:0] fill = 3'h1;
localparam [2:0] heat_w = 3'h2;
localparam [2:0] wash = 3'h3;
localparam [2:0] drain = 3'h4; //
reg [8*8-1:0] current_state1;
always @(uStateMachine.current_state)
begin
case (uStateMachine.current_state)
idle : current_state1 = "idle";
fill : current_state1 = "fill";
heat_w : current_state1 = "heat_w";
wash : current_state1 = "wash";
drain : current_state1 = "drain";
endcase
end
reg [8*8-1:0] next_state1;
always @(uStateMachine.next_state)
begin
case (uStateMachine.next_state)
idle : next_state1 = "idle";
fill : next_state1 = "fill";
heat_w : next_state1 = "heat_w";
wash : next_state1 = "wash";
drain : next_state1 = "drain";
endcase
end
endmodule
vlib work
vlog StateMachine.v tb_StateMachine.v
vsim -t ns tb_StateMachine
view wave
add wave -radix binary /tb_StateMachine/clk
add wave -radix binary /tb_StateMachine/reset
add wave -divider <NULL>
add wave -radix unsigned /tb_StateMachine/uStateMachine/current_state
add wave -radix unsigned /tb_StateMachine/uStateMachine/next_state
add wave -radix ascii /tb_StateMachine/current_state1
add wave -radix ascii /tb_StateMachine/next_state1
add wave -group movement -radix unsigned /tb_StateMachine/uStateMachine/idle
add wave -group movement -radix unsigned /tb_StateMachine/uStateMachine/fill
add wave -group movement -radix unsigned /tb_StateMachine/uStateMachine/heat_w
add wave -group movement -radix unsigned /tb_StateMachine/uStateMachine/wash
add wave -group movement -radix unsigned /tb_StateMachine/uStateMachine/drain
add wave -divider <NULL>
add wave -radix binary /tb_StateMachine/door_closed
add wave -radix binary /tb_StateMachine/full
add wave -radix binary /tb_StateMachine/heat_demand
add wave -radix binary /tb_StateMachine/empty
add wave -radix binary /tb_StateMachine/done
add wave -divider <NULL>
add wave -radix binary /tb_StateMachine/water
add wave -radix binary /tb_StateMachine/spin
add wave -radix binary /tb_StateMachine/heat
add wave -radix binary /tb_StateMachine/pump
run 500ns
modelsim에서 ascii 출력
`define Latency
module StateMachine (
input clk ,
input reset ,
input door_closed ,
input full ,
input heat_demand ,
input done ,
input empty ,
output reg water ,
output reg spin ,
output reg heat ,
output reg pump
);
reg [2:0] current_state, next_state;
parameter
idle = 0,
fill = 1,
heat_w = 2,
wash = 3,
drain = 4;
//reset
always @(posedge clk)
if(reset)
current_state <= idle;
else
current_state <= next_state;
`ifdef Latency
always @ (posedge clk)
begin
next_state = current_state; //default logic
case(current_state)
fill :
if (full)
next_state = heat_w;
heat_w :
if (!heat_demand)
next_state = wash;
wash :
begin
if(heat_demand)
next_state = heat_w;
if(done)
next_state = drain;
end
drain :
if(empty)
next_state = idle;
default :
if(door_closed)
next_state = fill;
endcase
end
`else
always @
begin
next_state = current_state; //default logic
case(current_state)
fill :
if (full)
next_state = heat_w;
heat_w :
if (!heat_demand)
next_state = wash;
wash :
begin
if(heat_demand)
next_state = heat_w;
if(done)
next_state = drain;
end
drain :
if(empty)
next_state = idle;
default :
if(door_closed)
next_state = fill;
endcase
end
`endif
`ifdef Latency
always @ (posedge clk)
begin
water = 0;
spin = 0;
heat = 0;
pump = 0;
case(next_state)
fill : begin
water = 1;
end
heat_w : begin
spin = 1;
heat = 1;
end
wash : begin
spin = 1;
end
drain : begin
spin = 1;
pump = 1;
end
default : ;
endcase
end
`else
always @ *
begin
water = 0;
spin = 0;
heat = 0;
pump = 0;
case(next_state)
fill : begin
water = 1;
end
heat_w : begin
spin = 1;
heat = 1;
end
wash : begin
spin = 1;
end
drain : begin
spin = 1;
pump = 1;
end
default : ;
endcase
end
`endif
endmodule
728x90
'[Harman] 하만 반도체 설계 > VerilogHDL' 카테고리의 다른 글
Day.85 Advanced Verilog #8 (0) | 2023.11.22 |
---|---|
Day.84 Advanced Verilog #7 (0) | 2023.11.20 |
Day.82 Advanced Verilog #5 (0) | 2023.11.15 |
Day.81 Advanced Verilog #4 (0) | 2023.11.14 |
Day.80 Advavnced Verilog #3 (0) | 2023.11.13 |