Kraklog

Day.83 Advanced Verilog #6 본문

[Harman] 하만 반도체 설계/VerilogHDL

Day.83 Advanced Verilog #6

Krakens 2023. 11. 17. 09:26
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

 

StateMachine View _ async reset

 

 

Transitions /  Encoding

 

wave form full

 

state machine _ sync reset
sync reset wave form full

 

AsyncReset_reset 적용

 

SyncReset_reset 적용

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