前言
????????相比之前的秒表,這個題目的難度略有提升,雖然總體架構(gòu)還是基于計數(shù)器的設(shè)計,但是需要添加其他的模塊,還是有些挑戰(zhàn)性的。
? ? ? ? 在代碼實現(xiàn)部分會給出設(shè)計理念和分析,整體資源可以直接下載壓縮包(手機端依然看不到,還是不知道為什么)。
題目需求及分析
需求
????????(1) 可以進(jìn)行不同分值的得分計數(shù);
????????(2) 用LED等表示裁判給出的犯規(guī)類型;
????????(3) 可以顯示當(dāng)前領(lǐng)先隊伍編號;
????????(4) 用循環(huán)彩燈設(shè)計啦啦隊加油信號。
分析
1、可以進(jìn)行不同分值的得分計數(shù),同時能實現(xiàn)兩組分?jǐn)?shù)的顯示
????????1,2,3三種得分,三個key1,2,3對應(yīng),按一下加一次分?jǐn)?shù);
? ? ? ? 通過sw1,sw2的開關(guān)來分別顯示兩隊的分值;
?? ??? ?補充一下,本來想的是開則顯示,關(guān)則不顯示,但是這樣會出現(xiàn)11的無效狀態(tài),00的狀態(tài)也沒有運用起來,比較浪費,所以這里擴展一下,合并3,sw1,2=00時清零分?jǐn)?shù),10時顯示紅隊,01時顯示藍(lán)隊,11時顯示優(yōu)先的隊伍標(biāo)號;
2、用LED等表示裁判給出的犯規(guī)類型
????????由于key鍵只有4個,所以這里需要分配一個sw,避免與得分沖突,3個key對應(yīng)三種犯規(guī),用三色燈表示;
3、可以顯示當(dāng)前領(lǐng)先隊伍編號
????????sw分配一個,打開顯示計數(shù)高的那一個;
4、用循環(huán)彩燈設(shè)計啦啦隊加油信號
????????打開就啟動流水燈(啦啦隊加油沒有限制);
5、輔助功能
? ? ? ? 顯然對于按鍵,需要有按鍵消抖的功能;顯示分?jǐn)?shù)則需要數(shù)碼管驅(qū)動模塊;而關(guān)于時序電路中必不可少的分頻器也是需要的;
代碼實現(xiàn)
由于CSDN編輯文章工具中沒有VDL語言的設(shè)置,這里就用C++來顯示代碼了(純黑實屬難看)。
1. 得分模塊
(1) 計分及顯示:scorer.v
module scorer(
input clk,
input rst, //重置分?jǐn)?shù)鍵
input getscore_1, //得1分,同時在sw1,2=11時,控制R燈
input getscore_2, //得2分,同時在sw1,2=11時,控制G燈
input getscore_3, //得3分,同時在sw1,2=11時,控制B燈
//功能選擇端,sw1,2=00時不工作,10時顯示一隊,01時顯示二隊,11時顯示優(yōu)先的隊伍序號
input sw1,
input sw2,
input sw3,
input sw4,
output [8:0] segment_led_1,segment_led_2, //數(shù)碼管輸出
output [7:0] led,
output R_led,
output G_led,
output B_led
);
reg [7:0] r_score; //內(nèi)部信號:紅隊分?jǐn)?shù)
reg [7:0] b_score; //內(nèi)部信號:藍(lán)隊分?jǐn)?shù)
reg [7:0] display; //顯示輸出
//得分模塊
always@(posedge clk_500hz)begin
//sw1,2=00,此時紅隊藍(lán)隊分?jǐn)?shù)全部清零,顯示FF,作為reset態(tài)
if(sw1 == 1'b0 && sw2 == 1'b0)begin
r_score[7:0] <= 8'h00;
b_score[7:0] <= 8'h00;
display[7:0] = 8'hff;
end
//sw1,2=10,此時顯示紅隊分?jǐn)?shù),可以改變紅隊分?jǐn)?shù)
else if(sw1 == 1'b1 && sw2 == 1'b0)begin
//清零
if(!rst)begin
r_score[7:0] <= 8'h00;
end
//得1分
else if(!getscore_1 && key_done)begin
if(r_score[3:0] < 4'd9)begin
r_score[3:0] <= r_score[3:0]+2'd1;
r_score[7:4] <= r_score[7:4];
end
else if(r_score[3:0] == 4'd9)begin
r_score[3:0] <= 4'h0;
r_score[7:4] <= r_score[7:4]+4'h1;
end
end
//得2分
else if(!getscore_2 && key_done)begin
if(r_score[3:0] < 4'd8)begin
r_score[3:0] <= r_score[3:0]+2'd2;
r_score[7:4] <= r_score[7:4];
end
else if(r_score[3:0] == 4'd8)begin
r_score[3:0] <= 4'h0;
r_score[7:4] <= r_score[7:4]+4'h1;
end
else if(r_score[3:0] == 4'd9)begin
r_score[3:0] <= 4'h1;
r_score[7:4] <= r_score[7:4]+4'h1;
end
end
//得3分
else if(!getscore_3 && key_done)begin
if(r_score[3:0] < 4'd7)begin
r_score[3:0] <= r_score[3:0]+2'd3;
r_score[7:4] <= r_score[7:4];
end
else if(r_score[3:0] == 4'd7)begin
r_score[3:0] <= 4'h0;
r_score[7:4] <= r_score[7:4]+4'h1;
end
else if(r_score[3:0] == 4'd8)begin
r_score[3:0] <= 4'h1;
r_score[7:4] <= r_score[7:4]+4'h1;
end
else if(r_score[3:0] == 4'd9)begin
r_score[3:0] <= 4'h2;
r_score[7:4] <= r_score[7:4]+4'h1;
end
end
//將紅隊分?jǐn)?shù)賦值給顯示
display[7:0] = r_score[7:0];
end
//sw1,2=01,此時顯示藍(lán)隊分?jǐn)?shù),可以改變藍(lán)隊分?jǐn)?shù)
else if((sw1 == 1'b0) & (sw2 == 1'b1))begin
//清零
if(!rst)begin
b_score[7:0] <= 8'h00;
end
//得1分
else if(!getscore_1 && key_done)begin
if(b_score[3:0] < 4'd9)begin
b_score[3:0] <= b_score[3:0]+2'd1;
b_score[7:4] <= b_score[7:4];
end
else if(b_score[3:0] == 4'd9)begin
b_score[3:0] <= 4'h0;
b_score[7:4] <= b_score[7:4]+4'h1;
end
end
//得2分
else if(!getscore_2 && key_done)begin
if(b_score[3:0] < 4'd8)begin
b_score[3:0] <= b_score[3:0]+2'd2;
b_score[7:4] <= b_score[7:4];
end
else if(b_score[3:0] == 4'd8)begin
b_score[3:0] <= 4'h0;
b_score[7:4] <= b_score[7:4]+4'h1;
end
else if(b_score[3:0] == 4'd9)begin
b_score[3:0] <= 4'h1;
b_score[7:4] <= b_score[7:4]+4'h1;
end
end
//得3分
else if(!getscore_3 && key_done)begin
if(b_score[3:0] < 4'd7)begin
b_score[3:0] <= b_score[3:0]+2'd3;
b_score[7:4] <= b_score[7:4];
end
else if(b_score[3:0] == 4'd7)begin
b_score[3:0] <= 4'h0;
b_score[7:4] <= b_score[7:4]+4'h1;
end
else if(b_score[3:0] == 4'd8)begin
b_score[3:0] <= 4'h1;
b_score[7:4] <= b_score[7:4]+4'h1;
end
else if(b_score[3:0] == 4'd9)begin
b_score[3:0] <= 4'h2;
b_score[7:4] <= b_score[7:4]+4'h1;
end
end
//將藍(lán)隊分?jǐn)?shù)賦值給顯示
display[7:0] = b_score[7:0];
end
//sw1,2=11,此時顯示分?jǐn)?shù)優(yōu)先的隊伍的序號,同時保持分?jǐn)?shù)不變
else if(sw1 == 1'b1 && sw2 == 1'b1)begin
r_score[7:0] <= r_score[7:0];
b_score[7:0] <= b_score[7:0];
if(r_score[7:0] < b_score[7:0])begin //藍(lán)隊領(lǐng)先,顯示01
display[7:0] = 8'h01;
end
else if(b_score[7:0] < r_score[7:0])begin //紅隊領(lǐng)先,顯示10
display[7:0] = 8'h10;
end
else //打平,顯示11
display[7:0] = 8'h11;
end
end
//例化數(shù)碼管顯示模塊
segment
(
.seg_data_1 (display[7:4]), //seg_data input
.seg_data_2 (display[3:0]), //seg_data input
.seg_led_1 (segment_led_1), //MSB~LSB = SEG,DP,G,F,E,D,C,B,A
.seg_led_2 (segment_led_2) //MSB~LSB = SEG,DP,G,F,E,D,C,B,A
);
//例化消抖module
wire key_done; //有按鍵按下
debounce //消抖模塊
(
.clk (clk),
.rst_n (rst),
.key_in1 (getscore_1),
.key_in2 (getscore_2),
.key_in3 (getscore_3),
.clk_500hz (clk_500hz),
.key_done (key_done)
);
//實例化流水燈
flashled
(
.clk (clk),
.rst (rst),
.sw3 (sw3), //控制開關(guān)
.led (led)
);
//實例化三色燈
RGB_LED
(
.clk (clk),
.rst (rst),
.sw4 (sw4),
.key_R (getscore_1),
.key_G (getscore_2),
.key_B (getscore_3),
.R_led (R_led),
.G_led (G_led),
.B_led (B_led)
);
endmodule
(2) 按鍵消抖:debounce.v
module debounce
(
input clk , //時鐘
input rst_n , //復(fù)位鍵
input key_in1, //對應(yīng)得1分鍵
input key_in2, //對應(yīng)得2分鍵
input key_in3, //對應(yīng)得3分鍵
output reg clk_500hz, //分頻出的500Hz時鐘脈沖信號(該板使用的是12M晶振)
output key_done //按鍵按下動作完成標(biāo)志
);
reg [25:0]div_cnt; //分頻計數(shù)器
always@(posedge clk or negedge rst_n)begin //獲得500Hz時鐘脈沖信號
if(!rst_n)begin
div_cnt <= 0;
clk_500hz <= 0;
end
else if(div_cnt == 1999)begin //計數(shù)兩千次反轉(zhuǎn)狀態(tài)
div_cnt <= 0;
clk_500hz <= ~clk_500hz;
end
else begin
div_cnt <= div_cnt + 1'b1;
clk_500hz <= clk_500hz;
end
end
reg qout;
reg key_tmp1,key_tmp2;
parameter n = 10;
reg [25:0] cnt;
always@(posedge clk_500hz or negedge rst_n) begin
if(!rst_n) begin
cnt <= 0;
qout <= 0;
end
else if(key_in1==0 || key_in2==0 || key_in3==0) begin //三個按鍵任意一個按下
if(cnt == n-1) begin //持續(xù)2ms的話判定按下
cnt <= cnt;
qout <= 1;
end
else begin
cnt <= cnt+1;
qout <= 0;
end
end
else begin
qout <= 0;
cnt <= 0;
end
end
//提取前后按鍵信號
always@(posedge clk_500hz or negedge rst_n) begin
if(!rst_n) begin
key_tmp1 <= 0;
key_tmp2 <= 0;
end
else begin
key_tmp1 <= qout;
key_tmp2 <= key_tmp1;
end
end
assign key_done = key_tmp1 & (~ key_tmp2);
endmodule
(3) 數(shù)碼管驅(qū)動:segment.v
module segment
(
input wire [3:0] seg_data_1, //四位輸入數(shù)據(jù)信號
input wire [3:0] seg_data_2, //四位輸入數(shù)據(jù)信號
output wire [8:0] seg_led_1, //數(shù)碼管1,MSB~LSB = SEG,DP,G,F,E,D,C,B,A
output wire [8:0] seg_led_2 //數(shù)碼管2,MSB~LSB = SEG,DP,G,F,E,D,C,B,A
);
reg[8:0] seg [15:0]; //存儲7段數(shù)碼管譯碼數(shù)據(jù)
initial
begin
seg[0] = 9'h3f; // 0
seg[1] = 9'h06; // 1
seg[2] = 9'h5b; // 2
seg[3] = 9'h4f; // 3
seg[4] = 9'h66; // 4
seg[5] = 9'h6d; // 5
seg[6] = 9'h7d; // 6
seg[7] = 9'h07; // 7
seg[8] = 9'h7f; // 8
seg[9] = 9'h6f; // 9
seg[10]= 9'h77; // A
seg[11]= 9'h7C; // b
seg[12]= 9'h39; // C
seg[13]= 9'h5e; // d
seg[14]= 9'h79; // E
seg[15]= 9'h71; // F
end
assign seg_led_1 = seg[seg_data_1];
assign seg_led_2 = seg[seg_data_2];
endmodule
2. 流水燈模塊
(1) 流水燈:flashled.v
module flashled (clk,rst,led,sw3);
input clk,rst,sw3;
output [7:0] led;
reg [2:0] cnt ; //定義了一個3位的計數(shù)器,輸出可以作為3-8譯碼器的輸入
wire clk1h; //定義一個中間變量,表示分頻得到的時鐘,用作計數(shù)器的觸發(fā)
//例化module decode38,相當(dāng)于調(diào)用
decode38 u1 (
.sw(cnt), //例化的輸入端口連接到cnt,輸出端口連接到led
.led(led)
);
//例化分頻器模塊,產(chǎn)生一個1Hz時鐘信號
divide #(.WIDTH(32),.N(12000000)) u2 ( //傳遞參數(shù)
.clk(clk),
.rst_n(rst), //例化的端口信號都連接到定義好的信號
.clkout(clk1h)
);
//1Hz時鐘上升沿觸發(fā)計數(shù)器,循環(huán)計數(shù)
always @(posedge clk1h or negedge rst)
if (!rst)
cnt <= 0;
else
cnt <= cnt +1;
endmodule
(2) 分頻器:divide.v
module divide ( clk,rst_n,clkout);
input clk,rst_n; //輸入信號,其中clk連接到FPGA的C1腳,頻率為12MHz
output clkout; //輸出信號,可以連接到LED觀察分頻的時鐘
//parameter是verilog里常數(shù)語句
parameter WIDTH = 3; //計數(shù)器的位數(shù),計數(shù)的最大值為 2**WIDTH-1
parameter N = 5; //分頻系數(shù),請確保 N < 2**WIDTH-1,否則計數(shù)會溢出
reg [WIDTH-1:0] cnt_p,cnt_n; //cnt_p為上升沿觸發(fā)時的計數(shù)器,cnt_n為下降沿觸發(fā)時的計數(shù)器
reg clk_p,clk_n; //clk_p為上升沿觸發(fā)時分頻時鐘,clk_n為下降沿觸發(fā)時分頻時鐘
//上升沿觸發(fā)時計數(shù)器的控制
always @ (posedge clk or negedge rst_n ) //posedge和negedge是verilog表示信號上升沿和下降沿
//當(dāng)clk上升沿來臨或者rst_n變低的時候執(zhí)行一次always里的語句
begin
if(!rst_n)
cnt_p<=0;
else if (cnt_p==(N-1))
cnt_p<=0;
else cnt_p<=cnt_p+1; //計數(shù)器一直計數(shù),當(dāng)計數(shù)到N-1的時候清零,這是一個模N的計數(shù)器
end
//上升沿觸發(fā)的分頻時鐘輸出,如果N為奇數(shù)得到的時鐘占空比不是50%;如果N為偶數(shù)得到的時鐘占空比為50%
always @ (posedge clk or negedge rst_n)
begin
if(!rst_n)
clk_p<=0;
else if (cnt_p<(N>>1)) //N>>1表示右移一位,相當(dāng)于除以2去掉余數(shù)
clk_p<=0;
else
clk_p<=1; //得到的分頻時鐘正周期比負(fù)周期多一個clk時鐘
end
//下降沿觸發(fā)時計數(shù)器的控制
always @ (negedge clk or negedge rst_n)
begin
if(!rst_n)
cnt_n<=0;
else if (cnt_n==(N-1))
cnt_n<=0;
else cnt_n<=cnt_n+1;
end
//下降沿觸發(fā)的分頻時鐘輸出,和clk_p相差半個時鐘
always @ (negedge clk)
begin
if(!rst_n)
clk_n<=0;
else if (cnt_n<(N>>1))
clk_n<=0;
else
clk_n<=1; //得到的分頻時鐘正周期比負(fù)周期多一個clk時鐘
end
assign clkout = (N==1)?clk:(N[0])?(clk_p&clk_n):clk_p; //條件判斷表達(dá)式
//當(dāng)N=1時,直接輸出clk
//當(dāng)N為偶數(shù)也就是N的最低位為0,N(0)=0,輸出clk_p
//當(dāng)N為奇數(shù)也就是N最低位為1,N(0)=1,輸出clk_p&clk_n。正周期多所以是相與
endmodule
(3) 38譯碼器:decode38.v
module decode38 (sw,led);
input [2:0] sw; //開關(guān)輸入信號,利用了其中3個開關(guān)作為3-8譯碼器的輸入
output [7:0] led; //輸出信號控制特定LED
reg [7:0] led; //定義led為reg型變量,在always過程塊中只能對reg型變量賦值
//always過程塊,括號中sw為敏感變量,當(dāng)sw變化一次執(zhí)行一次always中所有語句,否則保持不變
always @ (sw)
begin
case(sw) //case語句,一定要跟default語句
3'b000: led=8'b0111_1111; //條件跳轉(zhuǎn),其中“_”下劃線只是為了閱讀方便,無實際意義
3'b001: led=8'b1011_1111; //位寬'進(jìn)制+數(shù)值是Verilog里常數(shù)的表達(dá)方法,進(jìn)制可以是b、o、d、h(二、八、十、十六進(jìn)制)
3'b010: led=8'b1101_1111;
3'b011: led=8'b1110_1111;
3'b100: led=8'b1111_0111;
3'b101: led=8'b1111_1011;
3'b110: led=8'b1111_1101;
3'b111: led=8'b1111_1110;
default: ;
endcase
end
endmodule
3. 三色燈模塊
(1) 三色燈驅(qū)動:RGB_LED.v
module RGB_LED (
//這里之所以不采用連續(xù)賦值的方式來點亮LED的原因是,防止在整合模塊時發(fā)生管腳沖突的問題
clk,
rst,
sw4,
key_R,
key_G,
key_B,
R_led,
G_led,
B_led
);
input clk, rst, sw4, key_R, key_G, key_B;
output reg R_led, G_led, B_led;
always@(posedge clk_500hz)begin
if(sw4 == 1'b1)begin
if (!rst) //復(fù)位時led熄滅
R_led = 1;
else if(key_R == 0)
R_led = ~R_led; //按鍵按下時led翻轉(zhuǎn)
else
R_led = R_led;
if (!rst) //復(fù)位時led熄滅
G_led = 1;
else if(key_G == 0)
G_led = ~G_led; //按鍵按下時led翻轉(zhuǎn)
else
G_led = G_led;
if (!rst) //復(fù)位時led熄滅
B_led = 1;
else if(key_B == 0)
B_led = ~B_led; //按鍵按下時led翻轉(zhuǎn)
else
B_led = B_led;
end
end
//例化消抖module
wire key_done; //有按鍵按下
debounce //消抖模塊
(
.clk (clk),
.rst_n (rst),
.key_in1 (key_R),
.key_in2 (key_G),
.key_in3 (key_B),
.clk_500hz (clk_500hz),
.key_done (key_done)
);
endmodule
(2) 按鍵消抖:debounce.v
????????(同得分模塊下的按鍵消抖)
4. 管腳配置
? ? ? ? 作者使用的板子是“10M02SCM153C8G”核心板,用其他板子的話就換對應(yīng)的管腳就行。其中sw鍵是撥碼開關(guān),getscore和rst鍵是按鍵,led[i]是led燈,RGB_led是三色燈,clk是時鐘,segment是數(shù)碼管。
5. 設(shè)計過程中的一些錯誤和不足
????????1. 按照最初的構(gòu)想,作者是想要做如下圖的一個結(jié)構(gòu)的,頂層文件control.v做控制端,所有的子模塊在該文件中都是例化的情況。
????????但是在實現(xiàn)過程中,在control.v文件實例化scorer.v時會出現(xiàn)如下報錯,目前暫時不知道原因。處于“節(jié)省時間”的理由,轉(zhuǎn)而做成了現(xiàn)在結(jié)構(gòu),即以scorer.v為頂層文件,在scorer.v中實例化三色燈和流水燈模塊。
Error (10159): Verilog HDL error at control.v(22): "scorer" is not a task or void function
? ? ? ? ?2. 如上文所言,在該項目中我們是無法控制流水燈的,但原本在設(shè)計時本來是準(zhǔn)備用一個sw的開關(guān)來控制流水燈的開關(guān)。若在RGB_LED.v文件中添加如下控制代碼:
if(sw3 == 1'b0)
//RGB_LED.v中always下的代碼
? ? ? ? 則會出現(xiàn)如下報錯:在verilog文件中使用按鍵判斷時出現(xiàn)報錯。
????????大概原因是quartus2中不允許出現(xiàn)“不完整的閉環(huán)結(jié)構(gòu)”。這一點大概是代碼的邏輯問題,但是目前也沒有找出來具體是什么原因,所以干脆直接把控制端給刪了,讓流水燈一直亮著(啦啦隊一直加油也沒什么不對吧doge)。
Error (10200): Verilog HDL Conditional Statement error at flashled.v(27): cannot match operand(s) in the condition to the corresponding edges in the enclosing event control of the always construct
6. 可優(yōu)化
? ? ? ? 顯然,以上代碼實現(xiàn)的只是實現(xiàn)了題目的基本要求,在此基礎(chǔ)上還可以添加許多功能。sw_1,2,3,4四個撥碼開關(guān)作為工作狀態(tài)控制端,最多可以有16種功能。像籃球比賽中的24s倒計時,12min倒計時;大比分記錄這些功能都可以加進(jìn)去。
? ? ? ? 關(guān)于計時部分功能的添加,可以參考這個博主的,寫的很好,架構(gòu)也很清晰。
FPGA-籃球計分計時器的設(shè)計-CSDN博客
? ? ? ? 除去外加功能,已有功能也還有許多可以改進(jìn)的地方,如:1. 裁判判決模塊還可以加一個各種牌的累計數(shù);2. 流水燈顯然可以多幾種樣式,正傳、反轉(zhuǎn)、向中間和向兩邊都是可以的。
? ? ? ? 最后說一些關(guān)于項目開發(fā)的事兒,一個合格的項目,不僅不能有報錯,warning也應(yīng)該盡可能的少,但顯然作者沒能做到。
后記
一些感悟
? ? ? ? 1. 首先的首先,在一個完整的項目開發(fā)過程中,燒錄前是有仿真測試的。這一步的目的在于:通過仿真波形來檢查有沒有什么地方通過了編譯但是不符合使用要求的。比如在這次開發(fā)中,浪費了作者將近2個小時的一個點是:scorer.v中always用的時鐘是直接接的clk,而非分頻后的時鐘,于是在燒錄完后就出現(xiàn)了按下任意加分鍵,分?jǐn)?shù)都會隨機增加。其根本原因就是clk周期是1um,按一下的時間顯然不會次次相同,所以增加的分?jǐn)?shù)是隨機的。但是話又說回來,很慚愧的是,最后發(fā)現(xiàn)問題也不是通過仿真找出來的,而是在上課途中突然靈光乍現(xiàn),然后回來換了個時鐘就解決了......
? ? ? ? 2. 這次項目開發(fā)對于個人而言是一個很特殊的經(jīng)歷。在往常的項目開發(fā)中,作者秉持著優(yōu)先系統(tǒng)學(xué)習(xí)開發(fā)工具,在熟練運用后再來投入實踐。誠然,這種方法的好處是知識體系健全,開發(fā)能力牢固,但相應(yīng)的需要很長的學(xué)習(xí)周期,對于這個萬物日新月異的時代來說不是一個好的方法。反而這次對于FPGA的學(xué)習(xí)中,“以需求為導(dǎo)向”的學(xué)習(xí)方式是個更好的方法,遇到什么不會的就去查什么,慢慢的一點一點減少未知,最后下來差不多也算是掌握如何使用了。
? ? ? ? 3. 分模塊開發(fā)這一習(xí)慣一定要好好養(yǎng)成,完整來講,以上代碼都是第3還是第4版了,最初是按照得分模塊(下面還有單隊得分和雙隊得分兩個版本),流水燈模塊和三色燈模塊分別開發(fā)的,最后經(jīng)過整合后才做成了現(xiàn)在這個樣子。所以在“三色燈驅(qū)動”中有寫為什么不用數(shù)組來存狀態(tài),就是在整合中發(fā)現(xiàn)如果單獨整出個數(shù)組,配置管腳時就會沖突,所以改成了單個按鍵控制單個燈。但總的來說,這種先開發(fā)各個小模塊,最后整合的思路是極好的。
時間節(jié)點留言
2023.12.13
????????好好好歷時12個小時,終于給做出來了。好的方面講,實現(xiàn)了基本功能,至少是一個符合要求的,按照規(guī)定能夠使用的籃球比賽計分器;壞的方面講,其實還有很多地方時作者不太滿意的,時間充裕的情況下應(yīng)該好好優(yōu)化的,比如:頂層控制文件,又比如流水燈的控制端等等......
? ? ? ? 但是把,還有一個月就要期末考了,作者那成績屬實是慘不忍睹,雪上加霜的是,一邊還有個“智能儲物柜系統(tǒng)”沒整完,所以這個項目就只能草草了事了,實在是慚愧。
? ? ? ? 關(guān)于代碼和其他感悟,應(yīng)該能在明天晚上發(fā)出來,到時候會上傳全部文件的,需要的可以自取。
2023.12.14文章來源:http://www.zghlxwxcb.cn/news/detail-762068.html
? ? ? ? 還差一點,下午就能出來。
2023.12.14
? ? ? ? 暫時就寫這么多吧,之后有感悟了再回來補充。文章來源地址http://www.zghlxwxcb.cn/news/detail-762068.html
到了這里,關(guān)于【FPGA】籃球比賽計分器的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!