[2024.04.29.월] 인천인력개발원 하만 세미콘 아카데미
Verilog를 이용한 RTL 시스템 반도체 설계
FSM_SECURITY

1.36일차의 my_fsm_secure 프로젝트를 열고 Design Sources로 my_fsm_secure_top 추가

2. my_seg.v파일을 Design Sources로 추가 후 포트 정의

3. my_secure_top.v 코드 작성
`timescale 1ns / 1ps
module my_fsm_secure_top(
input RST,
input CLK,
input [1:0] KEY,
input SENSOR,
output ALARM_SIREN,
output CA,
output [6:0] AN
);
wire [1:0] fsm_state;
my_fsm_secure u0 (.RST (RST), .CLK (CLK), .KEY (KEY), .SENSOR (SENSOR),
.ALARM_SIREN (ALARM_SIREN), .FSM_STATE (fsm_state));
my_seg u1(.SW (fsm_state), .CA (CA), .AN(AN));
endmodule
4. my_seg.v 코드 작성
`timescale 1ns / 1ps
module my_seg(
input [1:0] SW,
output CA,
output reg [6:0] AN
);
parameter CLK_FREQ = 125_000_000;
assign CA = 1'b0;
always @(SW)
begin
case (SW)
2'b00 : AN = 7'h7c;
2'b01 : AN = 7'h60;
2'b10 : AN = 7'h6d;
2'b11 : AN = 7'h79;
endcase
end
endmodule
5. Open Elaborated Design 후 포트 할당

6. my_fsm_secure_top.v 코드 수정
module my_fsm_secure_top(
input RST,
input CLK,
input [1:0] KEY,
input SENSOR,
output ALARM_SIREN,
output CA,
output [6:0] AN,
output VCC
);
wire [1:0] fsm_state;
assign VCC = 1'b1;
7. VCC포트 추가 후 재할당

8. 위 과정 재수행 후 동작 확인
실습 2: 교통 신호기 FSM
1. my_traffic 프로젝트 생성
2. Add Design Sources로 time_chk.v 생성

3. 코드 작성
`timescale 1ns / 1ps
module time_chk(
input RST,
input CLK,
input [6:0] time_slot,
input start,
output [6:0] curr_slot,
output done
);
parameter CLK_FREQ = 125_000_000;
wire [39:0] MAX_CNT = time_slot * CLK_FREQ / 10;
reg [29:0] cnt;
always @(posedge CLK)
begin
if(RST)
cnt <= 30'd0;
else if(start)
cnt <= cnt + 1;
else
cnt <= 30'd0;
end
assign done = (cnt == MAX_CNT - 1);
assign curr_slot = cnt;
endmodule
4. Add Sources-Design Sources로 traffic_cnt 형성 후 포트 설정

5. 코드작성
`timescale 1ns / 1ps
module traffic_cnt(
input RST,
input CLK,
input PED_SW,
output reg RED,
output reg GREEN,
output reg YELLOW,
output reg WORK
);
parameter CLK_FREQ = 125_000_000;
localparam [1:0] //sIDLE = 3'd0
sYEL = 2'd0,
sRED = 2'd1,
sGREEN = 2'd2,
sPED = 2'd3;
reg [1:0] curr_state , next_state;
reg start_cnt;
wire cnt_done;
reg [6:0] time_slot;
wire [6:0] curr_slot;
reg [8:0] curr_time;
reg pd_sw_1d, pd_sw_2d;
wire pd_sw_rising;
always @(posedge CLK)
begin
if (RST)
curr_state <= sYEL;
else
curr_state <= next_state;
end
always @(RST, curr_state, cnt_done, PED_SW)
begin
if(RST) begin
next_state = sYEL;
start_cnt = 1'b0;
time_slot = 0;
RED = 1'b0;
GREEN = 1'b0;
YELLOW = 1'b0;
WORK = 1'b0;
end
else begin
RED = 1'b0;
GREEN = 1'b0;
YELLOW = 1'b0;
WORK = 1'b0;
case (curr_state)
sYEL: begin
time_slot = 10;
if (cnt_done) begin
next_state = sRED;
start_cnt = 1'b0;
end
else begin
next_state = sYEL;
start_cnt = 1'b1;
end
YELLOW = 1'b1;
end
sRED: begin
time_slot = 7'd80;
if (cnt_done) begin
start_cnt = 1'b0;
next_state = sGREEN;
end
else if(PED_SW) begin
next_state = sPED;
start_cnt = 1'b0;
end
else begin
start_cnt = 1'b1;
next_state = sRED;
end
RED = 1'b1;
end
sGREEN: begin
time_slot = 80;
if (cnt_done) begin
start_cnt = 1'b0;
next_state = sYEL;
end
else begin
start_cnt = 1'b1;
next_state = sGREEN;
end
GREEN = 1'b1;
WORK = 1'b1;
end
sPED: begin
if(curr_slot < 20 )
begin
time_slot = 20;
curr_time = 7'd0;
end
else begin
time_slot = 12;
curr_time = 7'd0;
end
if (cnt_done) begin
start_cnt = 1'b0;
next_state = sGREEN;
end
else begin
start_cnt = 1'b1;
next_state = sPED;
end
RED = 1'b1;
end
default : next_state = sYEL;
endcase
end //if-else
end //always
time_chk #(.CLK_FREQ (CLK_FREQ)) u0(
.RST (RST),
.CLK (CLK),
.time_slot (time_slot),
.start (start_cnt),
.curr_slot (curr_slot),
.done (cnt_done)
);
always @(posedge CLK)
begin
pd_sw_1d <= PED_SW;
pd_sw_2d <= pd_sw_1d;
end
assign pd_sw_rising = pd_sw_1d & ~pd_sw_2d;
always @(posedge CLK)
begin
if(curr_state == sYEL)
curr_time <= 7'd0;
else if (pd_sw_rising)
curr_time <= curr_slot;
end
endmodule
6. Testbench를 위해 traffic_tb파일 생성 후 코드 작성
`timescale 1ns / 1ps
module traffic_tb();
parameter CLK_PD = 10;
reg RST, CLK, PED_SW;
wire RED, GREEN, YELLOW, WORK;
traffic_cnt #(.CLK_FREQ(100))
uut (
.RST (RST),
.CLK (CLK),
.PED_SW (PED_SW),
.RED (RED),
.GREEN (GREEN),
.YELLOW (YELLOW),
.WORK (WORK)
);
initial begin
RST = 1'b1;
#(CLK_PD*20);
RST = 1'b0;
end
initial CLK = 1'b0;
always #(CLK_PD/2) CLK = ~CLK;
initial begin
PED_SW = 1'b0;
wait(RST == 1'b0);
wait(RED == 1'b1);
wait(RED == 1'b0);
wait(RED == 1'b1);
#(CLK_PD*12);
PED_SW = 1'b1;
#(CLK_PD*3);
PED_SW = 1'b0;
wait(GREEN == 1'b1);
wait(GREEN == 1'b0);
wait(YELLOW == 1'b1);
wait(YELLOW == 1'b0);
$finish;
end
endmodule
7. Behavioral Simulation 결과 확인

8. 포트 설정

9. 동작 확인