always@(posedge clk_L )
begin
if (reset)
begin
count <= 0;
pause_flag <= 0;
end
else if (pause_flag)
begin
if (!start_pre && start)
begin
count <= count+1;
pause_flag <= 0;
end
end
else if (!pause_pre && pause)
begin
count <= count;
pause_flag <= 1;
end
else
count <= count+1;
pause_pre <= pause;
start_pre <= start;
end
2017年11月14日 星期二
2017年11月8日 星期三
流水燈
//=======================================================
// This code is generated by Terasic System Builder
//=======================================================
module button_game2(
//////////// CLOCK //////////
CLOCK_50,
CLOCK2_50,
CLOCK3_50,
//////////// LED //////////
LEDG,
LEDR,
//////////// KEY //////////
KEY,
//////////// SW //////////
SW,
//////////// SEG7 //////////
HEX0,
HEX1,
HEX2,
HEX3,
HEX4,
HEX5,
HEX6,
HEX7
);
//=======================================================
// PARAMETER declarations
//=======================================================
//=======================================================
// PORT declarations
//=======================================================
//////////// CLOCK //////////
input CLOCK_50;
input CLOCK2_50;
input CLOCK3_50;
//////////// LED //////////
output [8:0] LEDG;
output [17:0] LEDR;
//////////// KEY //////////
input [3:0] KEY;
//////////// SW //////////
input [17:0] SW;
//////////// SEG7 //////////
output [6:0] HEX0;
output [6:0] HEX1;
output [6:0] HEX2;
output [6:0] HEX3;
output [6:0] HEX4;
output [6:0] HEX5;
output [6:0] HEX6;
output [6:0] HEX7;
//=======================================================
// REG/WIRE declarations
//=======================================================
wire [7:0] score;
wire [7:0] death;
wire [3:0] count_1kHz, count_100Hz, count_10Hz, count_1Hz;
wire clock_1Hz, clock_10Hz, clock_100Hz, clock_1kHz, clock_10kHz;
wire b10, b06, b03, b01;
//=======================================================
// Structural coding
//=======================================================
clock_all ck( .clk(CLOCK_50), .clock_10kHz(clock_10kHz), .clock_1kHz(clock_1kHz), .clock_100Hz(clock_100Hz), .clock_10Hz(clock_10Hz), .clock_1Hz(clock_1Hz));
// divider_10 div( .clk(~KEY[1]), .reset(~KEY[0]), .clk_div10(LEDR[0]), .count_10(count_1Hz) );
SEG7_LUT_8 seg( .oSEG0(HEX0),.oSEG1(HEX1),.oSEG2(HEX2),.oSEG3(HEX3),
.oSEG4(HEX4),.oSEG5(HEX5),.oSEG6(HEX6),.oSEG7(HEX7),
.iDIG( score) );
//PWM p0( .clk(clock_10kHz), .duty(100), .pwm(b10));
//PWM p1( .clk(clock_10kHz), .duty( 75), .pwm(b06));
//PWM p2( .clk(clock_10kHz), .duty( 50), .pwm(b03));
//PWM p3( .clk(clock_10kHz), .duty( 25), .pwm(b01));
// assign LEDR[17:0] = { b03, b01, 1'b0,b01, b03, b06, b10, b06, b03, b01, 1'b0, b01, b03, b06, b10, b06, b03, b01};
LEDR_wave L0( .clk_L(clock_10Hz), .clk_H(clock_10kHz), .LEDR( LEDR), .count(score));
//assign LEDR[17] = clock_1Hz;
//assign LEDR[16] = clock_10Hz;
//shrew us( .clk(clock_1Hz), .reset(~SW[0]), .key(KEY), .show_shrew({LEDG[6], LEDG[4], LEDG[2], LEDG[0]}), .score(score), .death(LEDR) );
endmodule
module LEDR_wave(clk_L, clk_H, LEDR, count);
input clk_L, clk_H;
output reg [17:0] LEDR;
output reg [2:0] count;
wire b10, b06, b03, b01;
PWM p0( .clk(clk_H), .duty(100), .pwm(b10));
PWM p1( .clk(clk_H), .duty( 50), .pwm(b06));
PWM p2( .clk(clk_H), .duty( 20), .pwm(b03));
PWM p3( .clk(clk_H), .duty( 05), .pwm(b01));
always@(posedge clk_L )
begin
count <= count+1;
end
always @(count)
begin
case(count)
3'h00: LEDR[17:0] = { b10, b06, b03, b01,1'b0,1'b0,1'b0,1'b0, b10, b06, b03, b01,1'b0,1'b0,1'b0,1'b0, b10, b06};
3'h01: LEDR[17:0] = { b06, b03, b01,1'b0,1'b0,1'b0,1'b0, b10, b06, b03, b01,1'b0,1'b0,1'b0,1'b0, b10, b06, b10};
3'h02: LEDR[17:0] = { b03, b01,1'b0,1'b0,1'b0,1'b0, b10, b06, b03, b01,1'b0,1'b0,1'b0,1'b0, b10, b06, b10, b06};
3'h03: LEDR[17:0] = { b01,1'b0,1'b0,1'b0,1'b0, b10, b06, b03, b01,1'b0,1'b0,1'b0,1'b0, b10, b06 ,b10, b06, b03};
3'h04: LEDR[17:0] = {1'b0,1'b0,1'b0,1'b0, b10, b06, b03, b01,1'b0,1'b0,1'b0,1'b0, b10, b06 ,b10, b06, b03, b01};
3'h05: LEDR[17:0] = {1'b0,1'b0,1'b0, b10, b06, b03, b01,1'b0,1'b0,1'b0,1'b0, b10, b06 ,b10, b06, b03, b01,1'b0};
3'h06: LEDR[17:0] = {1'b0,1'b0, b10, b06, b03, b01,1'b0,1'b0,1'b0,1'b0, b10, b06 ,b10, b06, b03, b01,1'b0,1'b0};
3'h07: LEDR[17:0] = {1'b0, b10, b06, b03, b01,1'b0,1'b0,1'b0,1'b0, b10, b06 ,b10, b06, b03, b01,1'b0,1'b0,1'b0};
endcase
end
endmodule
Verilog 時脈產生器
主程式
clock_all.v
clock_all.v
以下程式可在Quartus II 利用modelsim後模擬,且可在電路正確執行,但無法在Modelsim裡正確的前模擬,因為沒有初始值時,Modelsim無法進行運算。
- // Quartus II Verilog Template
- // Binary up/down counter
- // Main clock 50MHz.
- module clock_all(
- input clk,
- output clock_1MHz,
- output clock_100kHz,
- output clock_10kHz,
- output clock_1kHz,
- output clock_100Hz,
- output clock_10Hz,
- output clock_1Hz,
- output clock_01Hz
- );
- divider_50 clk0( .clk(clk), .clk_div50(clock_1MHz));
- divider_10 clk1( .clk(clock_1MHz), .clk_div10(clock_100kHz));
- divider_10 clk2( .clk(clock_100kHz), .clk_div10(clock_10kHz));
- divider_10 clk3( .clk(clock_10kHz), .clk_div10(clock_1kHz));
- divider_10 clk4( .clk(clock_1kHz), .clk_div10(clock_100Hz));
- divider_10 clk5( .clk(clock_100Hz), .clk_div10(clock_10Hz));
- divider_10 clk6( .clk(clock_10Hz), .clk_div10(clock_1Hz));
- divider_10 clk7( .clk(clock_1Hz), .clk_div10(clock_01Hz));
- endmodule
- //=========================================
- module divider_10(
- input clk,
- output reg clk_div10,
- output reg [3:0] count_10
- );
- always @ (posedge clk)
- begin
- if (count_10==4)
- begin
- count_10 <= 0;
- clk_div10<=~clk_div10;
- end
- else
- count_10 <= count_10 + 1;
- end
- endmodule
- //=========================================
- module divider_50(
- input clk,
- output reg clk_div50,
- output reg [4:0] count_50
- );
- always @ (posedge clk)
- begin
- if (count_50==24)
- begin
- count_50 <= 0;
- clk_div50<=~clk_div50;
- end
- else
- count_50 <= count_50 + 1;
- end
- endmodule
在Quartus II模擬的test bench 如下:
clock_all_tb.v
- `timescale 1ns/1ns
- module clock_all_tb;
- reg clk;
- wire clock_1MHz;
- wire clock_100kHz;
- clock_all u(
- .clk(clk),
- .clock_1MHz(clock_1MHz),
- .clock_100kHz(clock_100kHz)
- );
- initial
- begin
- #0
- clk = 0;
- end
- always
- #10 clk = ~clk;
- endmodule
當直接使用Modelsim作前模擬時,所有的wire或reg宣告都需要有初始值,需要利用reset使訊號歸零。程式改為
clock_all.v
- // Quartus II Verilog Template
- // Binary up/down counter
- // Main clock 50MHz.
- module clock_all(
- input clk,
- input rst,
- output clock_1MHz,
- output clock_100kHz,
- output clock_10kHz,
- output clock_1kHz,
- output clock_100Hz,
- output clock_10Hz,
- output clock_1Hz,
- output clock_01Hz,
- output [4:0] count_50
- );
- divider_50 clk0( .clk(clk), .rst(rst), .clk_div50(clock_1MHz), .count_50(count_50));
- divider_10 clk1( .clk(clock_1MHz), .rst(rst), .clk_div10(clock_100kHz));
- divider_10 clk2( .clk(clock_100kHz), .rst(rst), .clk_div10(clock_10kHz));
- divider_10 clk3( .clk(clock_10kHz), .rst(rst), .clk_div10(clock_1kHz));
- divider_10 clk4( .clk(clock_1kHz), .rst(rst), .clk_div10(clock_100Hz));
- divider_10 clk5( .clk(clock_100Hz), .rst(rst), .clk_div10(clock_10Hz));
- divider_10 clk6( .clk(clock_10Hz), .rst(rst), .clk_div10(clock_1Hz));
- divider_10 clk7( .clk(clock_1Hz), .rst(rst), .clk_div10(clock_01Hz));
- endmodule
- //=========================================
- module divider_10(
- input clk,
- input rst,
- output reg clk_div10,
- output reg [3:0] count_10
- );
- always @ (posedge clk or negedge rst)
- begin
- if (!rst)
- begin
- count_10 <= 0;
- clk_div10<= 0;
- end
- else if (count_10==4)
- begin
- count_10 <= 0;
- clk_div10<=~clk_div10;
- end
- else
- count_10 <= count_10 + 1;
- end
- endmodule
- //=========================================
- module divider_50(
- input clk,
- input rst,
- output reg clk_div50,
- output reg [4:0] count_50
- );
- always @ (posedge clk or negedge rst)
- begin
- if (!rst)
- begin
- count_50 <= 0;
- clk_div50<= 0;
- end
- else if (count_50==24)
- begin
- count_50 <= 0;
- clk_div50<=~clk_div50;
- end
- else
- count_50 <= count_50 + 1;
- end
- endmodule
test bench 的程式檔如下
clock_all_tb.v
- `timescale 1ns/1ns
- module clock_all_tb;
- reg rst;
- reg clk;
- wire clock_1MHz;
- wire clock_100kHz;
- clock_all u(
- .clk(clk),
- .rst(rst),
- .clock_1MHz(clock_1MHz),
- .clock_100kHz(clock_100kHz)
- );
- initial
- begin
- #0
- clk = 0;
- rst = 0;
- #30 rst = 1;
- end
- always
- #10 clk = ~clk;
- endmodule
clock_all.v
- // Quartus II Verilog Template
- // Binary up/down counter
- // Main clock 50MHz.
- module clock_all(
- input clk,
- input rst,
- output clock_10MHz,
- output clock_1MHz,
- output clock_100kHz,
- output clock_10kHz,
- output clock_1kHz,
- output clock_100Hz,
- output clock_10Hz,
- output clock_1Hz,
- output clock_01Hz,
- output [4:0] count_50
- );
- divider_5 clk0( .clk(clk), .rst(rst), .clk_div5(clock_10MHz));
- divider_10 clk1( .clk(clock_10MHz), .rst(rst), .clk_div10(clock_1MHz));
- divider_10 clk2( .clk(clock_1MHz), .rst(rst), .clk_div10(clock_100kHz));
- divider_10 clk3( .clk(clock_100kHz), .rst(rst), .clk_div10(clock_10kHz));
- divider_10 clk4( .clk(clock_10kHz), .rst(rst), .clk_div10(clock_1kHz));
- divider_10 clk5( .clk(clock_1kHz), .rst(rst), .clk_div10(clock_100Hz));
- divider_10 clk6( .clk(clock_100Hz), .rst(rst), .clk_div10(clock_10Hz));
- divider_10 clk7( .clk(clock_10Hz), .rst(rst), .clk_div10(clock_1Hz));
- divider_10 clk8( .clk(clock_1Hz), .rst(rst), .clk_div10(clock_01Hz));
- endmodule
- //=========================================
- module divider_10(
- input clk,
- input rst,
- output reg clk_div10,
- output reg [3:0] count_10
- );
- always @ (posedge clk or negedge rst)
- begin
- if (!rst)
- begin
- count_10 <= 0;
- clk_div10<= 0;
- end
- else if (count_10==4)
- begin
- count_10 <= 0;
- clk_div10<=~clk_div10;
- end
- else
- count_10 <= count_10 + 1;
- end
- endmodule
- //=========================================
- module divider_5(
- input clk,
- input rst,
- output clk_div5
- );
- reg clk_div5p, clk_div5n;
- reg [2:0] count_5p, count_5n;
- always @ (posedge clk or negedge rst)
- begin
- if (!rst)
- begin
- count_5p <= 0;
- end
- else if (count_5p==4)
- begin
- count_5p <= 0;
- end
- else
- begin
- count_5p <= count_5p + 1;
- end
- end
- always @ (posedge clk or negedge rst)
- begin
- if (!rst)
- begin
- clk_div5p<= 0;
- end
- else if (count_5p<=1)
- begin
- clk_div5p<=1'b1;
- end
- else
- begin
- clk_div5p<=1'b0;
- end
- end
- always @ (posedge clk or negedge rst)
- begin
- if (!rst)
- begin
- count_5n <= 0;
- end
- else if (count_5n==4)
- begin
- count_5n <= 0;
- end
- else
- begin
- count_5n <= count_5n + 1;
- end
- end
- always @ (negedge clk or negedge rst)
- begin
- if (!rst)
- begin
- clk_div5n<= 0;
- end
- else if (count_5n<=1)
- begin
- clk_div5n<=1'b1;
- end
- else
- begin
- clk_div5n<=1'b0;
- end
- end
- assign clk_div5 = clk_div5p | clk_div5n;
- endmodule
測試用的test bench
clock_all_tb.v
- `timescale 1ns/1ns
- module clock_all_tb;
- reg rst;
- reg clk;
- wire clock_10MHz;
- wire clock_1MHz;
- wire clock_100kHz;
- clock_all u(
- .clk(clk),
- .rst(rst),
- .clock_10MHz(clock_10MHz),
- .clock_1MHz(clock_1MHz),
- .clock_100kHz(clock_100kHz)
- );
- initial
- begin
- #0
- clk = 0;
- rst = 0;
- #100 rst = 1;
- end
- always
- #10 clk = ~clk;
- endmodule
其中,module divider_5係用來將時脈除5,其工作原理係分別使用輸入時脈clk的正、負邊緣觸發。正邊緣觸發clk_div5p在第0及第1兩個完整週期輸出為高準位,負邊緣觸發clk_div5n在第0.5至第2.5兩個週期間輸出為高準位,最後再取or運算,得到2.5週期的高準位。
訂閱:
文章 (Atom)