[1] StopWatch 설계 후, FSM (sw[0], sw[1]) 으로 Stop, Run, Clear 상태 제어. stopwatch 내부에 clkDivider 와 0.1s Counter 가 필요하다. clkDivider 는 10hz, Counter 는 0 ~ 9999 까지 Count 하도록 설계한다(14bit). fig.1 과 같이 FSM 의 stoprun 신호를 받을 수 있는 enable 과 clear 신호를 받는 reset(clear) port 를 선언해주어야 한다.
`timescale 1ns / 1ps
module stopwatch(
input clk,
input reset,
input i_run_stop,
input i_clear,
output [13:0] o_upCounter
);
wire w_clk;
clkDivider_10hz U_clkDivider_10hz(
.clk(clk),
.reset(reset),
.i_clear(i_clear),
.i_enable(i_run_stop),
.o_clk(w_clk)
);
upcounter U_upcounter(
.clk(w_clk),
.reset(reset),
.i_clear(i_clear),
.o_upCounter(o_upCounter)
);
endmodule
module clkDivider_10hz (
input clk,
input reset,
input i_clear,
input i_enable,
output reg o_clk
);
reg [31:0] r_counter = 0;
always@(posedge clk, posedge reset, posedge i_clear) begin
if(reset || i_clear) begin
r_counter <= 0;
o_clk <= 1'b0;
end else if(i_enable) begin
if(r_counter == 10_000_000 - 1) begin // 10hz
r_counter <= 0;
o_clk <= 1'b1;
end else begin
r_counter <= r_counter + 1;
o_clk <= 1'b0;
end
end
else r_counter <= r_counter;
end
endmodule
module upcounter (
input clk,
input reset,
input i_clear,
output reg [13:0] o_upCounter = 0
);
always@(posedge clk, posedge reset, posedge i_clear) begin
if(reset || i_clear) begin
o_upCounter <= 0;
end
else begin
if(o_upCounter == 9999) begin
o_upCounter <= 0;
end
else begin
o_upCounter <= o_upCounter + 1;
end
end
end
endmodule
FSM : Run, Stop, Clear
Moore Machine
Current | nextState | - | ||||
reset | input | state | output | state | ||
stoprun | clear | |||||
1 | - | - | 0 | 0 | STOP | |
0 | sw[0] = 1 | STOP | 1 | 0 | RUN | i_stoprunSW |
0 | sw[1] = 1 | STOP | 0 | 1 | CLEAR | i_clearSW |
0 | sw[0] = 0 | STOP | 0 | 0 | STOP | else |
0 | sw[1] = 0 | STOP | 0 | 0 | STOP | else |
0 | sw[0] = 0 | RUN | 0 | 0 | STOP | !i_stoprunSW |
0 | sw[0] = 1 | RUN | 1 | 0 | RUN | else |
0 | sw[1] = 0 | CLEAR | 0 | 0 | STOP | !i_clearSW |
0 | sw[1] = 1 | CLEAR | 0 | 1 | CLEAR | |
default | 0 | 0 | STOP |
`timescale 1ns / 1ps
module FSM_stopwatch(
input clk,
input reset,
input i_stoprunSW, // i_a[0]
input i_clearSW, // i_a[1]
output reg o_stoprun,
output reg o_clear
);
parameter S_STOP = 2'd0, S_RUN = 2'd1, S_CLEAR = 2'd2;
reg [1:0] state = S_STOP, nextState ;
always @(posedge clk, posedge reset) begin
if(reset) state <= S_STOP;
else state <= nextState;
end
always @(*) begin
case (state)
S_STOP : begin
if(i_stoprunSW) nextState <= S_RUN;
else if(i_clearSW) nextState <= S_CLEAR;
else nextState <= S_STOP;
end
S_RUN : begin
if(!i_stoprunSW) nextState <= S_STOP;
else nextState <= S_RUN;
end
S_CLEAR : begin
if(!i_clearSW) nextState <= S_STOP;
else nextState <= S_CLEAR;
end
default : nextState <= S_STOP;
endcase
end
always @(*) begin
case (state)
S_STOP : begin
o_stoprun = 1'b0;
o_clear = 1'b0;
end
S_RUN : begin
o_stoprun = 1'b1;
o_clear = 1'b0;
end
S_CLEAR : begin
o_stoprun = 1'b0;
o_clear = 1'b1;
end
default : begin
o_stoprun = 1'b0;
o_clear = 1'b0;
end
endcase
end
endmodule
[2] mux 의 sw[15] 로 Calculator, StopWatch 동작 제어. mux 를 통해 FndController 에 {5'b0, w_sum} 와 [13:0] o_counter, 중 하나를 선택해서 내보낸다.
`timescale 1ns / 1ps
module mux_2x1_14bit(
input i_sel, // i_b[7] = sw[15]
input [13:0] i_x0, // Calculator_Value
input [13:0] i_x1, // stopwatch_Value
output reg [13:0] o_y
);
always @(*) begin
case (i_sel)
1'b0 : o_y = i_x0;
1'b1 : o_y = i_x1;
default: o_y = 14'b0;
endcase
end
endmodule
`timescale 1ns / 1ps
module Calculator_8bit_FSM_stopwatch (
input clk,
input reset,
input [7:0] i_a,
input [7:0] i_b,
output [3:0] o_digitSel,
output [7:0] o_fndFont
);
wire [8:0] w_sum;
wire w_stoprun, w_clear;
wire [13:0] w_stopwatchValue, w_FndsourceValue;
FSM_stopwatch U_FSM_stopwatch(
.clk(clk),
.reset(reset),
.i_stoprunSW(i_a[0]),
.i_clearSW(i_a[1]),
.o_stoprun(w_stoprun),
.o_clear(w_clear)
);
stopwatch U_stopwatch(
.clk(clk),
.reset(reset),
.i_run_stop(w_stoprun),
.i_clear(w_clear),
.o_upCounter(w_stopwatchValue)
);
adder_8bit U_adder_8bit(
.i_a(i_a),
.i_b(i_b),
.o_sum(w_sum[7:0]),
.o_carry(w_sum[8])
);
mux_2x1_14bit U_mux_2x1_14bit(
.i_sel(i_b[7]),
.i_x0({5'b0, w_sum}),
.i_x1(w_stopwatchValue),
.o_y(w_FndsourceValue)
);
FndController U_FndController(
.clk(clk),
.reset(reset),
.i_sw_bcd(w_FndsourceValue),
.o_digitSel(o_digitSel),
.o_fndFont(o_fndFont)
);
endmodule
'[Harman] 반도체 설계 > Vivado' 카테고리의 다른 글
[Vivado] 0X. Source Code (0) | 2023.08.05 |
---|---|
[Vivado] 07. Calculator 8bit, PB FSM StopWatch (0) | 2023.08.05 |
[Vivado] 05. Finite State Machine LED (0) | 2023.08.05 |
[Vivado] 04. FndController, Adder 8bit (0) | 2023.08.05 |
[Vivado] 03. Adder 8bit (0) | 2023.08.05 |