[2024.04.26.금] 인천인력개발원 하만 세미콘 아카데미
Verilog를 이용한 RTL 시스템 반도체 설계
FSM State Diagram
1. 버튼이 눌리면 STR_STP변수를 1과 0으로 변경하여 모드를 Start, Stop으로 변경하는 모듈 작성
- Switch를 누르면 CLK의 rising edge에 맞춰 ss_1d를 1로
- 다음 CLK의 rising edge에서도 switch가 1이면 ss_2d를 1로
Encoding Methods p.317
p.326
mealy finite state machine p.330
FSM Coding Guidlines p.341
Avoiding Race Conditions in Veriog p. 356
실습: FSM Demo
1. Vivado 실행 후 my_fsm 프로젝트 생성
2. INPUT은 RST, CLK, [1:0] SW / OUTPUT은 [1:0] LED로 설정
3. 코드 작성
`timescale 1ns / 1ps
module my_fsm(
input RST,
input CLK,
input [1:0] SW,
output reg [1:0] LED
);
localparam [1:0] idle = 2'b00,
state_a = 2'b01,
state_b = 2'b10,
state_c = 2'b11;
reg [1:0] curr_state, next_state;
always @(posedge CLK)
begin
if (RST)
curr_state <= idle;
else
curr_state <= next_state;
end //always end
always @(curr_state, SW)
begin
case (curr_state)
idle : begin
if(SW == 2'b01)
next_state = state_a;
else
next_state = idle;
LED = 2'b00;
end
state_a : begin
if(SW == 2'b10)
next_state = state_b;
else
next_state = state_a;
LED = 2'b01;
end
state_b : begin
if(SW == 2'b11)
next_state = state_c;
else
next_state = state_b;
LED = 2'b10;
end
state_c : begin
if(SW == 2'b00)
next_state = idle;
else
next_state = state_c;
LED = 2'b11;
end
default: next_state = idle;
endcase
end //always end
endmodule
4. 테스트벤치 파일 생성 후 코드 작성
- parmaeter로 클록의 주기 설정: parameter CLK_PD = 10.0;
- 위 코드의 INPUT은 변경 가능하므로 reg로, OUTPUT은 변경 불가하므로 wire로 선언
- my_fsm uut ( );를 이용하여 포트 맵핑
`timescale 1ns / 1ps module my_fsm_tb(); parameter CLK_PD = 10.0; reg RST, CLK; reg [1:0] SW; wire [1:0] LED; my_fsm uut( .RST (RST), .CLK (CLK), .SW (SW), .LED (LED) ); endmodule
- RST을 켰다 꺼준 뒤, CLK신호를 생성하기 위한 코드 작성
initial begin RST = 1'b1; #(CLK_PD*20); RST = 1'b0; end initial CLK = 1'b0; always #(CLK_PD/2) CLK = ~CLK;
- 스위치를 주기적으로 바꾸기 위한 코드 작성
initial begin SW = 2'b00; wait (RST == 1'b0); #(CLK_PD*10); SW = 2'b01; #(CLK_PD*10); SW = 2'b10; #(CLK_PD*10); SW = 2'b11; #(CLK_PD*10); SW = 2'b00; end
5. Behavioral Simulation 진행 후 결과 확인
6. Board에 스위치를 연결하기 전에 my_fsm.v파일의 INPUT 파트 코드 수정
module my_fsm(
input RST,
input CLK,
input [1:0] SW,
output reg [1:0] LED,
output VCC,
output GND
);
assign VCC = 1'b1;
assign GND = 1'b0;
7. Open Elaborated Design 수행 후 I/O Planning에서 포트 지정
8. Run Implementation - my_fsm으로 save
9. Generate Bitstream
10. Open H/W Manager -> Open Target -> Program Device
11. 핀 설정에서 오류(작동 x)로 인해 핀 재설정
- OUTPUT의 GND 없애고, 스위치 장착 위치 변경 후 I/O Planning
- Elaborated Design Reload - Generate Bitstream 후 Program Device
12. 동작 확인
실습: FSM Sequrity
- SW가 00 -> 해제 / 11 -> 잠금
1. my_fsm_secure project 생성 후 my_fsm_secure.v 코드 작성
`timescale 1ns / 1ps
module my_fsm_secure(
input CLK,
input RST,
input [1:0] KEY,
input SENSOR,
output reg ALARM_SIREN,
output reg [1:0] FSM_STATE
);
parameter CLK_FREQ = 125_000_000;
localparam [1:0] disarmed = 2'b00,
armed = 2'b01,
wait_delay = 2'b10,
alarm = 2'b11;
reg [1:0] curr_state, next_state;
wire cnt_done;
reg start_cnt;
reg [29:0] cnt;
always @(posedge CLK)
if(RST)
curr_state <= disarmed;
else
curr_state <= next_state;
always @(curr_state, KEY, SENSOR, cnt_done)
begin
start_cnt = 1'b0;
ALARM_SIREN = 1'b0;
case(curr_state)
disarmed : begin
if(KEY == 2'b11)
next_state = armed;
else
next_state = disarmed;
FSM_STATE = 2'b00;
end
armed : begin
if(SENSOR == 1'b1)
next_state = wait_delay;
else if( KEY == 2'b00)
next_state = disarmed;
else
next_state = armed;
FSM_STATE = 2'b01;
end
wait_delay : begin
start_cnt = 1'b1;
if(cnt_done == 1'b1)
next_state = alarm;
else if( KEY == 2'b00)
next_state = disarmed;
else
next_state = wait_delay;
FSM_STATE = 2'b10;
end
alarm : begin
if( KEY == 2'b00)
next_state = disarmed;
else
next_state = alarm;
FSM_STATE = 2'b11;
end
default : next_state = disarmed;
endcase
end
always @(posedge CLK)
begin
if (RST)
cnt <= 30'd0;
else if(start_cnt)
cnt <= cnt + 1;
else
cnt <= 30'd0;
end //always
assign cnt_done = cnt == (CLK_FREQ*5 - 1);
endmodule
2. 테스트벤치를 위해 my_secure_tb.v Simulation Source를 추가하고 코드 작성
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2024/04/26 15:34:55
// Design Name:
// Module Name: my_fsm_security_tb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module my_fsm_secure_tb();
parameter CLK_PD = 8.00;
reg RST, CLK;
reg [1:0] KEY;
reg SENSOR;
wire alarm_siren;
wire [1:0] fsm_state;
my_fsm_secure uut(
.CLK (CLK),
.RST (RST),
.KEY (KEY),
.SENSOR (SENSOR),
.ALARM_SIREN (alarm_siren),
.FSM_STATE (fsm_state)
);
initial begin
RST = 1'b1;
#(CLK_PD*10);
RST = 1'b0;
end
initial CLK = 1'b0;
always #(CLK_PD/2) CLK = ~CLK;
initial begin
KEY = 2'b00;
SENSOR = 1'b0;
wait (RST == 1'b0);
#(CLK_PD*10);
KEY = 2'b01; //armed
#(CLK_PD*10);
KEY = 2'b10; //disarmed
#(CLK_PD*10);
KEY = 2'b11; //armed
#(CLK_PD*10);
SENSOR = 1'b1;
wait (alarm_siren == 1'b1);
#(CLK_PD*10);
KEY = 2'b0; //disarmed
SENSOR = 1'b0;
#(CLK_PD*10);
$finish;
end
endmodule
3. Behavioral Simulation 결과 확인