Author Topic: Learn FPGA from scratch  (Read 16857 times)

0 Members and 1 Guest are viewing this topic.

Offline suzhimingTopic starter

  • Contributor
  • !
  • Posts: 46
  • Country: cn
Re: Learn FPGA from scratch
« Reply #25 on: June 17, 2025, 03:45:49 pm »
2593715-0
 

Offline suzhimingTopic starter

  • Contributor
  • !
  • Posts: 46
  • Country: cn
Re: Learn FPGA from scratch
« Reply #26 on: July 27, 2025, 04:23:43 pm »
* maichong2.zip (1.36 kB - downloaded 28 times.)
power  =60;
 

Offline suzhimingTopic starter

  • Contributor
  • !
  • Posts: 46
  • Country: cn
Re: Learn FPGA from scratch
« Reply #27 on: July 27, 2025, 04:31:12 pm »

modelsim simulation.
 

Offline suzhimingTopic starter

  • Contributor
  • !
  • Posts: 46
  • Country: cn
Re: Learn FPGA from scratch
« Reply #28 on: August 01, 2025, 02:59:05 pm »
我只是太无聊了,所以我添加了按钮。

[/*************脉冲发生器, 100hz_2路互补****************/
/*************EPM240T100C5N*************************/
/*************ID:共同学习FPGA************************/
/*************20250715*****************************/
//系统时钟100Mhz,设定频率100k,定时时间0-511个脉冲,死区时间32个脉冲;
//B+----------------------------------直径1mm*5镀银丝35T
//        |        |        |        |
//      s1|      s3|      S5|      s7|
//        |---L1---|        |---L2---|
//      s2|      s4|      S6|      s8|
//        |        |        |        |
//B-----------------------------------

//num        |0___________________511|
//num        |__________50%__________|100%
//num        |12345|6789a|12345|6789a|
//L1         |___0-255___|___________|
//L2         |___________|_256-511___|

//s1         |¯¯¯¯¯|_________________|
//s2         |_____|¯¯¯¯¯|___________|
//s3         |_____|¯¯¯¯¯|___________|
//s4         |¯¯¯¯¯|_________________|
//s5         |___________|¯¯¯¯¯|_____|
//s6         |_________________|¯¯¯¯¯|
//s7         |___________|¯¯¯¯¯|_____|
//s8         |_________________|¯¯¯¯¯|

//           -|-k_jia        //加键
//           -|-k_jian       //减键
//`timescale 1ns/10ps
module maichong
(
clk,      //系统时钟100MHz;
res,      //复位信号,低电平有效;
k_jia,      //按键加
k_jian,      //按键减
s1,      //桥臂1上管;
s2,      //桥臂1下管;
s3,      //桥臂2上管;
s4,      //桥臂2下管;
s5,      //桥臂3上管;
s6,      //桥臂3下管;
s7,      //桥臂4上管;
s8       //桥臂4下管;
);

input            clk;
input            res;
input            k_jia;
input            k_jian;

output reg      s1;
output reg      s2;
output reg      s3;
output reg      s4;
output reg      s5;
output reg      s6;
output reg      s7;
output reg      s8;

reg[8:0]         num;                     //计数器;
reg[8:0]         power;                  //功率;
reg[8:0]         k_num;                  //按键计数器;

parameter      siqu         =16;         //死区时间;
parameter      zuixiao      =128;         //最小数50%-100%;
parameter      xiang1      =5;         //第一相起始点;
parameter      xiang2      =260;         //第二相起始点;
parameter      k_max         =200;         //按键消抖阈值;


`define         shu         (zuixiao +power)
`define         shu_ban      ((zuixiao +power) >>1)



always@(posedge clk or negedge res)
if(~res)
begin
s1         <=0;
s2         <=0;
s3         <=0;
s4         <=0;
s5         <=0;
s6         <=0;
s7         <=0;
s8         <=0;
num      <=0;
power      <=60;
k_num      <=0;

end

else
begin
/**************************************************/      //计数器
num      <=num   +1;
/**************************************************/      //第一相

if((num >xiang1) && (num <(`shu_ban -siqu) ))         //前半个周期
begin
s1      <=1;
s4      <=1;
end
else
begin
s1      <=0;
s4      <=0;
end

if((num >`shu_ban) && ( num <(`shu -siqu)))            //后半个周期
begin
s2      <=1;
s3      <=1;
end
else
begin
s2      <=0;
s3      <=0;
end
/**************************************************/      //第二相

if((num >xiang2) && (num <(xiang2 +(`shu_ban -siqu)) ))         //前半个周期
begin
s5      <=1;
s8      <=1;
end
else
begin
s5      <=0;
s8      <=0;
end

if((num >(xiang2 +(`shu_ban -siqu)) ) && (num <(xiang2 +(`shu -siqu))) )            //后半个周期
begin
s6      <=1;
s7      <=1;
end
else
begin
s6      <=0;
s7      <=0;
end



/**************************************************/            //511时更新按键;
if(num ==511)
begin
if(!k_jia || !k_jian)
begin
k_num      <=k_num +1;
if(k_num ==k_max)
begin
if(!k_jia  && power <100 )         begin power <=power+1; k_num <=0; end
else if(!k_jian && power >40 )   begin power <=power-1; k_num <=0; end
end
end
else
begin
k_num <=0;
end
end
/**************************************************/



end
endmodule

/******************testbench of maichong***********/
module maichong_tb;
reg      clk, res, k_jia, k_jian;
wire   s1, s2, s3, s4, s5, s6, s7, s8;
maichong   maichong
(
.clk(clk),      //系统时钟100MHz;
.res(res),      //复位信号,低电平有效;
.k_jia(k_jia),      //按键加
.k_jian(k_jian),      //按键减
.s1(s1),      //桥臂1上管;
.s2(s2),      //桥臂1下管;
.s3(s3),      //桥臂2上管;
.s4(s4),      //桥臂2下管;
.s5(s5),      //桥臂3上管;
.s6(s6),      //桥臂3下管;
.s7(s7),      //桥臂4上管;
.s8(s8)       //桥臂4下管;
);

initial
begin
clk      <=0;
res      <=0;
#20      res      <=1;
#1000      k_jia      <=0;
#1000      k_jia      <=1;
#1000      k_jia      <=0;
#1000      k_jia      <=1;
#1000      k_jia      <=0;
#1000      k_jia      <=1;
#120000   $stop;

end
always      #5         clk      <=~clk;
always      #10000      k_jia   <=~k_jia;
endmodule
/**************************************************/
/**************************************************/
/**************************************************/
/**************************************************/























[随员=1]]
 

Offline suzhimingTopic starter

  • Contributor
  • !
  • Posts: 46
  • Country: cn
Re: Learn FPGA from scratch
« Reply #29 on: August 01, 2025, 03:03:37 pm »
cod* maichong2.zip (1.36 kB - downloaded 29 times.)
 

Offline zapta

  • Super Contributor
  • ***
  • Posts: 6566
  • Country: 00
Re: Learn FPGA from scratch
« Reply #30 on: August 01, 2025, 04:33:08 pm »
Code: [Select]
The forums software removed the indentation. Try to use the [#] button (code).

  begin
     ...
  end
 

Offline suzhimingTopic starter

  • Contributor
  • !
  • Posts: 46
  • Country: cn
Re: Learn FPGA from scratch
« Reply #31 on: August 19, 2025, 03:40:13 pm »
pcb_bmp
 

Offline suzhimingTopic starter

  • Contributor
  • !
  • Posts: 46
  • Country: cn
Re: Learn FPGA from scratch
« Reply #32 on: August 19, 2025, 03:41:54 pm »
pcb_json
« Last Edit: August 19, 2025, 03:43:33 pm by suzhiming »
 

Offline suzhimingTopic starter

  • Contributor
  • !
  • Posts: 46
  • Country: cn
Re: Learn FPGA from scratch
« Reply #33 on: August 31, 2025, 03:09:18 pm »

Continuously upgrading
 

Offline suzhimingTopic starter

  • Contributor
  • !
  • Posts: 46
  • Country: cn
Re: Learn FPGA from scratch
« Reply #34 on: September 09, 2025, 03:05:49 am »
new02
 

Offline suzhimingTopic starter

  • Contributor
  • !
  • Posts: 46
  • Country: cn
Re: Learn FPGA from scratch
« Reply #35 on: September 11, 2025, 05:01:14 pm »



/*************EPM240T100C5N************************/


//`timescale 1ns/10ps
module led4
               (
               clk,   
               led


               );


input            clk;
input            res;
output    reg[11:0]      led;


reg[24:0]      num;      //num* led4.zip (227.44 kB - downloaded 29 times.);
//reg[11:0]      led;      //;
always@(posedge clk or negedge res)
if(~res)
   begin
   num         <=0;
   end


else
begin
   if(num      ==6_000_000)
      begin
      num      <=0;
      end
   else
      begin
      num      <=num +1;
      end
end


always@(posedge clk or negedge res)
begin
if(~res)
   begin
   led      <=12'b111_111_111_110;
   end
else
   begin
      if(num      ==6_000_000)
         begin
         led      <={led[10:0], led[11] };
         end
   end


end


endmodule




   
   
   
   
   
   
   
   
   
   

 

Offline suzhimingTopic starter

  • Contributor
  • !
  • Posts: 46
  • Country: cn
Re: Learn FPGA from scratch
« Reply #36 on: September 14, 2025, 12:29:16 pm »
The Second Optimization
 

Offline suzhimingTopic starter

  • Contributor
  • !
  • Posts: 46
  • Country: cn
Re: Learn FPGA from scratch
« Reply #37 on: September 14, 2025, 04:14:08 pm »
 

Offline suzhimingTopic starter

  • Contributor
  • !
  • Posts: 46
  • Country: cn
Re: Learn FPGA from scratch
« Reply #38 on: September 17, 2025, 03:11:09 pm »
UP,2.2version
 

Offline suzhimingTopic starter

  • Contributor
  • !
  • Posts: 46
  • Country: cn
Re: Learn FPGA from scratch
« Reply #39 on: September 18, 2025, 03:53:05 pm »
0-99 display:


Code: [Select]
/*****************数码管****************************/
/*************EPM240T100C5N************************/
/*************ID:共同学习FPGA************************/
/*************20250915*****************************/
module led5
(
input clk, //系统时钟24MHz;
input res, //复位信号,低电平有效;
output reg led_1, //led_1;
output reg led_2,
output reg[7:0]x_c1, //数码管1,低L;
output reg[7:0]x_c2, //数码管2,低H;
output reg[7:0]x_c3, //数码管3,高L;
output reg[7:0]x_c4 //数码管4,高H;
);

reg[24:0] num; //num计数器;
reg num1; //秒脉冲尖;
/**************************************************/
always@(posedge clk or negedge res) //1.计时
if(~res)
begin
num <=0;
num1 <=0;
end

else
begin
if(num >=12_000_000 -1)
begin
num <=0;
num1 <=1;
end
else
begin
num <=num +1;
num1 <=0;
end
end


/**************************************************/
reg[7:0] x_a1; //数码管寄存器0-99;
reg[3:0] x_b1; //数码管低;
reg[3:0] x_b2; //数码管高;

//reg[7:0] x_a2; //数码管高0-99;
//reg[7:0] x_b3; //数码管低;
//reg[7:0] x_b4; //数码管高;


always@(posedge clk or negedge res) //2.显示
begin
if(~res)
begin
led_1 <=0;
led_2 <=0;
x_a1 <=0;
x_b1 <=0;
x_b2 <=0;
x_c1 <='b1111_1001; //1;
x_c2 <='b1111_1001; //2;
x_c3 <='b1111_1001; //3;
x_c4 <='b1111_1001; //4;
end
else
begin
if(num1)
begin
led_1 <=~led_1;
led_2 <=~led_2;
x_a1 <=(x_a1 >=99) ?0 : x_a1 +1;
x_b1 <=x_a1 % 10; //个位
x_b2 <=x_a1 / 10; //十位
end
case(x_b1) //个位;
4'd0: x_c1 = 8'hC0;  // 0
4'd1: x_c1 = 8'hF9;  // 1
4'd2: x_c1 = 8'hA4;  // 2
4'd3: x_c1 = 8'hB0;  // 3
4'd4: x_c1 = 8'h99;  // 4
4'd5: x_c1 = 8'h92;  // 5
4'd6: x_c1 = 8'h82;  // 6
4'd7: x_c1 = 8'hF8;  // 7
4'd8: x_c1 = 8'h80;  // 8
4'd9: x_c1 = 8'h90;  // 9
default: x_c1 = 8'hff; // 默认不显
endcase
 
case(x_b2) //十位
4'd0: x_c2 = 8'hC0;  // 0
4'd1: x_c2 = 8'hF9;  // 1
4'd2: x_c2 = 8'hA4;  // 2
4'd3: x_c2 = 8'hB0;  // 3
4'd4: x_c2 = 8'h99;  // 4
4'd5: x_c2 = 8'h92;  // 5
4'd6: x_c2 = 8'h82;  // 6
4'd7: x_c2 = 8'hF8;  // 7
4'd8: x_c2 = 8'h80;  // 8
4'd9: x_c2 = 8'h90;  // 9
default: x_c2 = 8'hff; // 默认不显
endcase

end

end

/**************************************************/
endmodule
/**************************************************/


 

Offline powersupply

  • Contributor
  • Posts: 15
  • Country: us
  • I have 14 multimeters, what is wrong with me.
Re: Learn FPGA from scratch
« Reply #40 on: September 24, 2025, 06:10:36 am »
I really fell in love with PSOC design environments. I think I bought all of them. Their IDE has a design palette where preconfigured components can be dragged and dropped onto a schematic, analog and digital designs can be created. They include 16 8 bit aclu’s which can be cascaded for up to 32 bits. You use VHDL to write code for the aclus. The only code you have to write is code to configure and activate each component. One of my favorites is the filter design built in component. You can literally draw your response curve and the component will act accordingly. You have to know digital and analog electronics, but it is such a powerful tool I have designed computer nodes that perform back propagation neural nets that take analog inputs filter appropriately and provide desired output. All in one chip. Very few external components are needed if you so desire. Your multipage schematic is inside the chip. It’s amazing. Infineon purchased PSOC and now focuses on PSOC 6, I prefer the PSOC 5LP. There design boards are about 60 dollars and the IDE is free. You get 159 preconfigured components of various complexity. I’m not affiliated with them but wish I was.
Thank you,

Measurement is everything.
 

Offline suzhimingTopic starter

  • Contributor
  • !
  • Posts: 46
  • Country: cn
Re: Learn FPGA from scratch
« Reply #41 on: October 03, 2025, 02:02:19 pm »
Code: [Select]
/*****************数码管****************************/
/*************EPM240T100C5N************************/
/*************ID:共同学习FPGA************************/
/*************20251003*****************************/
module led5
(
input clk, //系统时钟24MHz;
input res, //复位信号,低电平有效;
output reg led_1, //led_1;
output reg led_2, //led_2;
output reg[7:0]x_c1, //数码管1字模,个位;
output reg[7:0]x_c2, //数码管2字模,十位;
output reg[7:0]x_c3, //数码管3字模,百位;
output reg[7:0]x_c4 //数码管4字模,千位;
);
/**************************************************/ //1.计时
reg[24:0] num; //num计数器;
reg num1; //秒脉冲尖;
reg[7:0] shi; //时
reg[7:0] fen; //分
reg[7:0] miao; //秒
always@(posedge clk or negedge res)
begin
if(~res)
begin
num <=0;
num1 <=0;
shi <=8'b0001_0010;
fen <=0;
miao <=0;
end

else
begin
if(num ==1_000_000 -1)
begin
num <=0;
/**************************************************/ //时间计算;
if(miao[3:0]  > 4'd8)
begin
miao[3:0] <=0;


if(miao[7:4]  > 4'd4)
begin
miao[7:4] <=0;
if(fen[3:0]  > 4'd8)
begin
fen[3:0] <=0;
end
else
begin
fen[3:0] <=fen[3:0] +1;

end
end
else
begin
miao[7:4] <=miao[7:4] +1;
end
end
else
begin
miao[3:0] <=miao[3:0] +1;
end
/**************************************************/
num1 <=1;
end
else
begin
num <=num +1;
num1 <=0;
end
end
end
/**************************************************/

/**************************************************/ //2.显示
reg[15:0] x_a1; //十位,个位;
reg[15:0] x_a2; //千位,百位;
reg[3:0] x_b1; //数码管1数字,个位;
reg[3:0] x_b2; //数码管2数字,十位;
reg[3:0] x_b3; //数码管3数字,百位;
reg[3:0] x_b4; //数码管4数字,千位;
/**************************************************/
parameter seg_0 =8'hc0, //0
seg_1 =8'hf9, //1
seg_2 =8'ha4, //2
seg_3 =8'hb0, //3
seg_4 =8'h99, //4
seg_5 =8'h92, //5
seg_6 =8'h82, //6
seg_7 =8'hf8, //7
seg_8 =8'h80, //8
seg_9 =8'h90, //9
seg_A =8'h88, //A
seg_B =8'h83, //B
seg_C =8'hc6, //C
seg_D =8'ha1, //D
seg_E =8'h86, //E
seg_F =8'h8e, //F
seg_off =8'hff; //熄灭
/**************************************************/
always@(posedge clk or negedge res)
begin
if(~res)
begin
x_a1 <=0;
x_a2 <=0;
x_b1 <=0;
x_b2 <=0;
x_b3 <=0;
x_b4 <=0;
x_c1 <='b1001_1001; //4;
x_c2 <='b1011_0000; //3;
x_c3 <='b1010_0100; //2;
x_c4 <='b1111_1001; //1;
end
/**************************************************/
else
begin
if(num1)

begin
led_1 <=~led_1;
led_2 <=~led_2;
x_b1 <=miao[3:0];
x_b2 <=miao[7:4];
x_b3 <=fen[3:0];
x_b4 <=fen[7:4];
/**************************************************/
case(x_b1) //个位;
0: x_c1 = seg_0; // 0
1: x_c1 = seg_1; // 1
2: x_c1 = seg_2; // 2
3: x_c1 = seg_3; // 3
4: x_c1 = seg_4; // 4
5: x_c1 = seg_5; // 5
6: x_c1 = seg_6; // 6
7: x_c1 = seg_7; // 7
8: x_c1 = seg_8; // 8
9: x_c1 = seg_9; // 9
10: x_c1 = seg_A; // A
11: x_c1 = seg_B; // B
12: x_c1 = seg_C; // C
13: x_c1 = seg_D; // D
14: x_c1 = seg_E; // E
15: x_c1 = seg_F; // F
default: x_c1 = seg_off; // 不显
endcase
/**************************************************/
case(x_b2) //十位;
0: x_c2 = seg_0; // 0
1: x_c2 = seg_1; // 1
2: x_c2 = seg_2; // 2
3: x_c2 = seg_3; // 3
4: x_c2 = seg_4; // 4
5: x_c2 = seg_5; // 5
6: x_c2 = seg_6; // 6
7: x_c2 = seg_7; // 7
8: x_c2 = seg_8; // 8
9: x_c2 = seg_9; // 9
10: x_c2 = seg_A; // A
11: x_c2 = seg_B; // B
12: x_c2 = seg_C; // C
13: x_c2 = seg_D; // D
14: x_c2 = seg_E; // E
15: x_c2 = seg_F; // F
default: x_c2 = seg_off; // 不显
endcase
/**************************************************/
case(x_b3) //百位
0: x_c3 = seg_0; // 0
1: x_c3 = seg_1; // 1
2: x_c3 = seg_2; // 2
3: x_c3 = seg_3; // 3
4: x_c3 = seg_4; // 4
5: x_c3 = seg_5; // 5
6: x_c3 = seg_6; // 6
7: x_c3 = seg_7; // 7
8: x_c3 = seg_8; // 8
9: x_c3 = seg_9; // 9
10: x_c3 = seg_A; // A
11: x_c3 = seg_B; // B
12: x_c3 = seg_C; // C
13: x_c3 = seg_D; // D
14: x_c3 = seg_E; // E
15: x_c3 = seg_F; // F
default: x_c3 = seg_off; // 不显
endcase
/**************************************************/
case(x_b4) //千位
0: x_c4 = seg_0; // 0
1: x_c4 = seg_1; // 1
2: x_c4 = seg_2; // 2
3: x_c4 = seg_3; // 3
4: x_c4 = seg_4; // 4
5: x_c4 = seg_5; // 5
6: x_c4 = seg_6; // 6
7: x_c4 = seg_7; // 7
8: x_c4 = seg_8; // 8
9: x_c4 = seg_9; // 9
10: x_c4 = seg_A; // A
11: x_c4 = seg_B; // B
12: x_c4 = seg_C; // C
13: x_c4 = seg_D; // D
14: x_c4 = seg_E; // E
15: x_c4 = seg_F; // F
default: x_c4 = seg_off; // 不显
endcase
end
end
end
/**************************************************/
endmodule
/**************************************************/

[attachimg=1]
 

Offline suzhimingTopic starter

  • Contributor
  • !
  • Posts: 46
  • Country: cn
Re: Learn FPGA from scratch
« Reply #42 on: October 04, 2025, 03:38:45 am »
Improved the clk

Code: [Select]
/**************************************************/ //时间计算;
if(miao[3:0]  > 4'd8)
begin
miao[3:0] <=0;
if(miao[7:4]  > 4'd4)
begin
miao[7:4] <=0;
if(fen[3:0] > 4'd8)
begin
fen[3:0] <=0;
if(fen[7:4] > 4'd4)
begin
fen[7:4] <=0;
if(shi[3:0]  > 4'd2)
begin
shi[3:0]  <=0;
if(shi[7:4] > 4'd1)
begin
shi[7:4] <=0;
end
else
begin
shi[7:4] <=shi[7:4] +1;
end
end
else
begin
shi[3:0] <=shi[3:0] +1;
end

end
else
begin
fen[7:4] <=fen[7:4] +1;
end
end
else
begin
fen[3:0] <=fen[3:0] +1;
end
end
else
begin
miao[7:4] <=miao[7:4] +1;
end
end
else
begin
miao[3:0] <=miao[3:0] +1;
end
/**************************************************/
 

Offline suzhimingTopic starter

  • Contributor
  • !
  • Posts: 46
  • Country: cn
Re: Learn FPGA from scratch
« Reply #43 on: October 04, 2025, 01:56:37 pm »
he key function has been added, though it's not quite perfect.



Code: [Select]
/*****************数码管****************************/
/*************EPM240T100C5N************************/
/*************ID:共同学习FPGA************************/
/*************20251003*****************************/
module led5
(
input clk, //系统时钟24MHz;
input res, //复位信号,低电平有效;
input k_jia, //加;
input k_jian, //减;
input k_ent, //确认;
output reg led_1, //led_1;
output reg led_2, //led_2;
output reg[7:0]x_c1, //数码管1字模,个位;
output reg[7:0]x_c2, //数码管2字模,十位;
output reg[7:0]x_c3, //数码管3字模,百位;
output reg[7:0]x_c4 //数码管4字模,千位;
);
/**************************************************/ //1.计时
reg[24:0] num; //num计数器;
reg num1; //秒脉冲尖;
reg[7:0] shi; //时
reg[7:0] fen; //分
reg[7:0] miao; //秒
always@(posedge clk or negedge res)
begin
if(~res)
begin
num <=0;
num1 <=0;
shi <=8'b0001_0010;
fen <=0;
miao <=0;
end

else
begin
if(num ==24_000_000 -1)
begin
num <=0;
/**************************************************/ //时间计算;
if(miao[3:0] >4'd8)
begin
miao[3:0] <=4'd0;
if(miao[7:4] >4'd4)
begin
miao[7:4] <=4'd0;
if(fen[3:0] >4'd8)
begin
fen[3:0] <=4'd0;
if(fen[7:4] > 4'd4)
begin
fen[7:4] <=4'd0;
if(shi[3:0] >4'd2)
begin
shi[3:0] <=4'd0;
if(shi[7:4] >4'd1)
begin
shi[7:4] <=4'd0;
end
else
begin
shi[7:4] <=shi[7:4] +4'd1;
end
end
else
begin
shi[3:0] <=shi[3:0] +4'd1;
end

end
else
begin
fen[7:4] <=fen[7:4] +4'd1;
end
end
else
begin
fen[3:0] <=fen[3:0] +4'd1;
end
end
else
begin
miao[7:4] <=miao[7:4] +4'd1;
end
end
else
begin
miao[3:0] <=miao[3:0] +4'd1;
end
/**************************************************/

/**************************************************/ //按键
if(k_jia ==0) //分钟加
begin
if(fen > 8'd88)
begin
fen <=8'd0;
end
else
begin
fen <=fen +8'd1;
end
end


if(k_ent ==0) //分钟减
begin
if(fen > 8'd89)
begin
fen <=8'd89;
end
else
begin
fen <=fen -8'd1;
end
end

if(k_jian ==0) //小时
begin
if(shi > 8'd34)
begin
shi <=8'd0;
end
else
begin
shi <=shi +8'd1;
end
end
/**************************************************/
num1 <=1; //刷新标志位
end
else
begin
num <=num +1;
num1 <=0;
end
end
end
/**************************************************/

/**************************************************/ //2.显示
reg[15:0] x_a1; //十位,个位;
reg[15:0] x_a2; //千位,百位;
reg[3:0] x_b1; //数码管1数字,个位;
reg[3:0] x_b2; //数码管2数字,十位;
reg[3:0] x_b3; //数码管3数字,百位;
reg[3:0] x_b4; //数码管4数字,千位;
/**************************************************/
parameter seg_0 =8'hc0, //0
seg_1 =8'hf9, //1
seg_2 =8'ha4, //2
seg_3 =8'hb0, //3
seg_4 =8'h99, //4
seg_5 =8'h92, //5
seg_6 =8'h82, //6
seg_7 =8'hf8, //7
seg_8 =8'h80, //8
seg_9 =8'h90, //9
seg_A =8'h88, //A
seg_B =8'h83, //B
seg_C =8'hc6, //C
seg_D =8'ha1, //D
seg_E =8'h86, //E
seg_F =8'h8e, //F
seg_off =8'hff; //熄灭
/**************************************************/
always@(posedge clk or negedge res)
begin
if(~res)
begin
x_a1 <=0;
x_a2 <=0;
x_b1 <=0;
x_b2 <=0;
x_b3 <=0;
x_b4 <=0;
x_c1 <='b1001_1001; //4;
x_c2 <='b1011_0000; //3;
x_c3 <='b1010_0100; //2;
x_c4 <='b1111_1001; //1;
end
/**************************************************/
else
begin
if(num1)

begin
led_1 <=~led_1;
led_2 <=~led_2;
x_b1 <=fen[3:0];
x_b2 <=fen[7:4];
x_b3 <=shi[3:0];
x_b4 <=shi[7:4];
/**************************************************/
case(x_b1) //个位;
0: x_c1 = seg_0; // 0
1: x_c1 = seg_1; // 1
2: x_c1 = seg_2; // 2
3: x_c1 = seg_3; // 3
4: x_c1 = seg_4; // 4
5: x_c1 = seg_5; // 5
6: x_c1 = seg_6; // 6
7: x_c1 = seg_7; // 7
8: x_c1 = seg_8; // 8
9: x_c1 = seg_9; // 9
10: x_c1 = seg_A; // A
11: x_c1 = seg_B; // B
12: x_c1 = seg_C; // C
13: x_c1 = seg_D; // D
14: x_c1 = seg_E; // E
15: x_c1 = seg_F; // F
default: x_c1 = seg_off; // 不显
endcase
/**************************************************/
case(x_b2) //十位;
0: x_c2 = seg_0; // 0
1: x_c2 = seg_1; // 1
2: x_c2 = seg_2; // 2
3: x_c2 = seg_3; // 3
4: x_c2 = seg_4; // 4
5: x_c2 = seg_5; // 5
6: x_c2 = seg_6; // 6
7: x_c2 = seg_7; // 7
8: x_c2 = seg_8; // 8
9: x_c2 = seg_9; // 9
10: x_c2 = seg_A; // A
11: x_c2 = seg_B; // B
12: x_c2 = seg_C; // C
13: x_c2 = seg_D; // D
14: x_c2 = seg_E; // E
15: x_c2 = seg_F; // F
default: x_c2 = seg_off; // 不显
endcase
/**************************************************/
case(x_b3) //百位
0: x_c3 = seg_0; // 0
1: x_c3 = seg_1; // 1
2: x_c3 = seg_2; // 2
3: x_c3 = seg_3; // 3
4: x_c3 = seg_4; // 4
5: x_c3 = seg_5; // 5
6: x_c3 = seg_6; // 6
7: x_c3 = seg_7; // 7
8: x_c3 = seg_8; // 8
9: x_c3 = seg_9; // 9
10: x_c3 = seg_A; // A
11: x_c3 = seg_B; // B
12: x_c3 = seg_C; // C
13: x_c3 = seg_D; // D
14: x_c3 = seg_E; // E
15: x_c3 = seg_F; // F
default: x_c3 = seg_off; // 不显
endcase
/**************************************************/
case(x_b4) //千位
0: x_c4 = seg_0; // 0
1: x_c4 = seg_1; // 1
2: x_c4 = seg_2; // 2
3: x_c4 = seg_3; // 3
4: x_c4 = seg_4; // 4
5: x_c4 = seg_5; // 5
6: x_c4 = seg_6; // 6
7: x_c4 = seg_7; // 7
8: x_c4 = seg_8; // 8
9: x_c4 = seg_9; // 9
10: x_c4 = seg_A; // A
11: x_c4 = seg_B; // B
12: x_c4 = seg_C; // C
13: x_c4 = seg_D; // D
14: x_c4 = seg_E; // E
15: x_c4 = seg_F; // F
default: x_c4 = seg_off; // 不显
endcase
end
end
end
/**************************************************/
endmodule
/**************************************************/


 

Offline suzhimingTopic starter

  • Contributor
  • !
  • Posts: 46
  • Country: cn
Re: Learn FPGA from scratch
« Reply #44 on: October 05, 2025, 01:28:33 pm »
Improved the key value limitation



Code: [Select]
/*****************数码管****************************/
/*************EPM240T100C5N************************/
/*************ID:共同学习FPGA************************/
/*************20251003*****************************/
module led5
(
input clk, //系统时钟24MHz;
input res, //复位信号,低电平有效;
input k_jia, //加;
input k_jian, //减;
input k_ent, //确认;
output reg led_1, //led_1;
output reg led_2, //led_2;
output reg[7:0]x_c1, //数码管1字模,个位;
output reg[7:0]x_c2, //数码管2字模,十位;
output reg[7:0]x_c3, //数码管3字模,百位;
output reg[7:0]x_c4 //数码管4字模,千位;
);
/**************************************************/ //1.计时
reg[24:0] num; //num计数器;
reg num1; //秒脉冲尖;
reg[7:0] shi; //时
reg[7:0] fen; //分
reg[7:0] miao; //秒
always@(posedge clk or negedge res)
begin
if(~res)
begin
num <=0;
num1 <=0;
shi <=8'b0001_0010;
fen <=0;
miao <=0;
end

else
begin
if(num ==24_000_000 -1)
begin
num <=0;
/**************************************************/ //时间计算;
if(miao[3:0] >4'd8)
begin
miao[3:0] <=4'd0;
if(miao[7:4] >4'd4)
begin
miao[7:4] <=4'd0;
if(fen[3:0] >4'd8)
begin
fen[3:0] <=4'd0;
if(fen[7:4] > 4'd4)
begin
fen[7:4] <=4'd0;
if(shi[3:0] >4'd2)
begin
shi[3:0] <=4'd0;
if(shi[7:4] >4'd1)
begin
shi[7:4] <=4'd0;
end
else
begin
shi[7:4] <=shi[7:4] +4'd1;
end
end
else
begin
shi[3:0] <=shi[3:0] +4'd1;
end

end
else
begin
fen[7:4] <=fen[7:4] +4'd1;
end
end
else
begin
fen[3:0] <=fen[3:0] +4'd1;
end
end
else
begin
miao[7:4] <=miao[7:4] +4'd1;
end
end
else
begin
miao[3:0] <=miao[3:0] +4'd1;
end
/**************************************************/

/**************************************************/ //按键
if(k_jia ==0) //分钟加
begin
if(fen > 8'd88) //88是58分
begin
fen <=8'd0;
end
else
begin
if(fen[3:0] >4'd8) //当个位为9时
begin
fen[3:0] <=4'd0;
fen[7:4] <=fen[7:4] +4'd1;
end
else
begin
fen <=fen +8'd1;
end
end
end


if(k_ent ==0) //分钟减
begin
if(fen > 8'd89 ||fen ==8'd0)
begin
fen <=8'd89; //89是59分
end
else
begin
if(fen[3:0] ==4'd0) //个位是0
begin
fen <={fen[7:4] -4'd1,4'd9};
end
else
begin
fen <=fen -8'd1;
end
end
end

if(k_jian ==0) //小时加
begin
if(shi > 8'd34)
begin
shi <=8'd0;
end
else
begin
//shi <=shi +8'd1;
if(shi[3:0] == 4'd9) //9进位
begin
shi <={shi[7:4] + 4'd1,4'd0};
end
else
begin
shi <={shi[7:4], shi[3:0] + 4'd1};
end
end
end
/**************************************************/
num1 <=1; //刷新标志位
end
else
begin
num <=num +1;
num1 <=0;
end
end
end
/**************************************************/

/**************************************************/ //2.显示
reg[15:0] x_a1; //十位,个位;
reg[15:0] x_a2; //千位,百位;
reg[3:0] x_b1; //数码管1数字,个位;
reg[3:0] x_b2; //数码管2数字,十位;
reg[3:0] x_b3; //数码管3数字,百位;
reg[3:0] x_b4; //数码管4数字,千位;
/**************************************************/
parameter seg_0 =8'hc0, //0
seg_1 =8'hf9, //1
seg_2 =8'ha4, //2
seg_3 =8'hb0, //3
seg_4 =8'h99, //4
seg_5 =8'h92, //5
seg_6 =8'h82, //6
seg_7 =8'hf8, //7
seg_8 =8'h80, //8
seg_9 =8'h90, //9
seg_A =8'h88, //A
seg_B =8'h83, //B
seg_C =8'hc6, //C
seg_D =8'ha1, //D
seg_E =8'h86, //E
seg_F =8'h8e, //F
seg_off =8'hff; //熄灭
/**************************************************/
always@(posedge clk or negedge res)
begin
if(~res)
begin
x_a1 <=0;
x_a2 <=0;
x_b1 <=0;
x_b2 <=0;
x_b3 <=0;
x_b4 <=0;
x_c1 <='b1001_1001; //4;
x_c2 <='b1011_0000; //3;
x_c3 <='b1010_0100; //2;
x_c4 <='b1111_1001; //1;
end
/**************************************************/
else
begin
if(num1)

begin
led_1 <=~led_1;
led_2 <=~led_2;
x_b1 <=fen[3:0];
x_b2 <=fen[7:4];
x_b3 <=shi[3:0];
x_b4 <=shi[7:4];
/**************************************************/
case(x_b1) //个位;
0: x_c1 = seg_0; // 0
1: x_c1 = seg_1; // 1
2: x_c1 = seg_2; // 2
3: x_c1 = seg_3; // 3
4: x_c1 = seg_4; // 4
5: x_c1 = seg_5; // 5
6: x_c1 = seg_6; // 6
7: x_c1 = seg_7; // 7
8: x_c1 = seg_8; // 8
9: x_c1 = seg_9; // 9
10: x_c1 = seg_A; // A
11: x_c1 = seg_B; // B
12: x_c1 = seg_C; // C
13: x_c1 = seg_D; // D
14: x_c1 = seg_E; // E
15: x_c1 = seg_F; // F
default: x_c1 = seg_off; // 不显
endcase
/**************************************************/
case(x_b2) //十位;
0: x_c2 = seg_0; // 0
1: x_c2 = seg_1; // 1
2: x_c2 = seg_2; // 2
3: x_c2 = seg_3; // 3
4: x_c2 = seg_4; // 4
5: x_c2 = seg_5; // 5
6: x_c2 = seg_6; // 6
7: x_c2 = seg_7; // 7
8: x_c2 = seg_8; // 8
9: x_c2 = seg_9; // 9
10: x_c2 = seg_A; // A
11: x_c2 = seg_B; // B
12: x_c2 = seg_C; // C
13: x_c2 = seg_D; // D
14: x_c2 = seg_E; // E
15: x_c2 = seg_F; // F
default: x_c2 = seg_off; // 不显
endcase
/**************************************************/
case(x_b3) //百位
0: x_c3 = seg_0; // 0
1: x_c3 = seg_1; // 1
2: x_c3 = seg_2; // 2
3: x_c3 = seg_3; // 3
4: x_c3 = seg_4; // 4
5: x_c3 = seg_5; // 5
6: x_c3 = seg_6; // 6
7: x_c3 = seg_7; // 7
8: x_c3 = seg_8; // 8
9: x_c3 = seg_9; // 9
10: x_c3 = seg_A; // A
11: x_c3 = seg_B; // B
12: x_c3 = seg_C; // C
13: x_c3 = seg_D; // D
14: x_c3 = seg_E; // E
15: x_c3 = seg_F; // F
default: x_c3 = seg_off; // 不显
endcase
/**************************************************/
case(x_b4) //千位
0: x_c4 = seg_0; // 0
1: x_c4 = seg_1; // 1
2: x_c4 = seg_2; // 2
3: x_c4 = seg_3; // 3
4: x_c4 = seg_4; // 4
5: x_c4 = seg_5; // 5
6: x_c4 = seg_6; // 6
7: x_c4 = seg_7; // 7
8: x_c4 = seg_8; // 8
9: x_c4 = seg_9; // 9
10: x_c4 = seg_A; // A
11: x_c4 = seg_B; // B
12: x_c4 = seg_C; // C
13: x_c4 = seg_D; // D
14: x_c4 = seg_E; // E
15: x_c4 = seg_F; // F
default: x_c4 = seg_off; // 不显
endcase
end
end
end
/**************************************************/
endmodule
/**************************************************/

[attachimg=1]
 

Offline bson

  • Supporter
  • ****
  • Posts: 2753
  • Country: us
Re: Learn FPGA from scratch
« Reply #45 on: October 06, 2025, 08:05:01 pm »
Improved the clk

Code: [Select]
/**************************************************/ //时间计算;
if(miao[3:0]  > 4'd8)
begin
miao[3:0] <=0;
if(miao[7:4]  > 4'd4)
begin
miao[7:4] <=0;
if(fen[3:0] > 4'd8)
begin
fen[3:0] <=0;
if(fen[7:4] > 4'd4)
begin
fen[7:4] <=0;
if(shi[3:0]  > 4'd2)
begin
shi[3:0]  <=0;
if(shi[7:4] > 4'd1)
begin
shi[7:4] <=0;
end
else
begin
shi[7:4] <=shi[7:4] +1;
end
end
else
begin
shi[3:0] <=shi[3:0] +1;
end

end
else
begin
fen[7:4] <=fen[7:4] +1;
end
end
else
begin
fen[3:0] <=fen[3:0] +1;
end
end
else
begin
miao[7:4] <=miao[7:4] +1;
end
end
else
begin
miao[3:0] <=miao[3:0] +1;
end
/**************************************************/

I'd suggest learning to use 'generate' and then rethink how you keep state.
 

Offline suzhimingTopic starter

  • Contributor
  • !
  • Posts: 46
  • Country: cn
Re: Learn FPGA from scratch
« Reply #46 on: October 09, 2025, 03:46:09 am »
Verilog is not executed line by line like C language. Currently, there are many bugs, so the code has been rewritten.

Code: [Select]
if(miao[7:4] == 8'd5 && miao[3:0] == 4'd9)
begin
miao <= 8'd0;
fen <= fen +8'd1;
end
else if(miao[3:0] == 4'd9)
begin
miao <= {miao[7:4] + 4'd1,4'd0};
end
else
begin
miao <= miao + 8'd1;
end
 

Offline suzhimingTopic starter

  • Contributor
  • !
  • Posts: 46
  • Country: cn
Re: Learn FPGA from scratch
« Reply #47 on: October 09, 2025, 03:47:02 pm »
It's better to write the program this way.



Code: [Select]
/**************************************************/ //秒进位
if(miao[7:4] == 4'd5 && miao[3:0] == 4'd9)
begin
miao <= 8'd0;
/**************************************************/ //分进位
if(fen[7:4] == 4'd5 && fen[3:0] == 4'd9)
begin
fen <= 8'd0;
/**************************************************/ //时进位
if(shi[7:4] == 4'd2 && shi[3:0] == 4'd4)
begin
shi <=8'd0;
end
else if(shi[3:0] == 4'd9 )
begin
shi <={shi[7:4] +4'd1,shi[3:0] <= 4'd0};
end
else
begin
shi <= shi +8'd1;
end
/**************************************************/
end
else if(fen[3:0] == 4'd9)
begin
fen <={fen[7:4] + 4'd1,4'd0};
end
else
begin
fen <= fen +8'd1;
end
/**************************************************/
end
else if(miao[3:0] == 4'd9)
begin
miao <= {miao[7:4] + 4'd1,4'd0};
end
else
begin
miao <= miao + 8'd1;
end
/**************************************************/
end
end
end
 

Offline suzhimingTopic starter

  • Contributor
  • !
  • Posts: 46
  • Country: cn
Re: Learn FPGA from scratch
« Reply #48 on: October 10, 2025, 02:21:24 pm »
That's better, using the bit concatenation operation.



Code: [Select]
/****************时钟*******************************/
/****************EPM240T100C5N*********************/
/****************ID:共同学习FPGA********************/
/****************20251010**************************/
module shizhong
(
input clk, //系统时钟24MHz;
input res, //复位信号,低电平有效;
input k_jia, //加;
input k_jian, //减;
input k_ent, //确认;
output reg led_1, //led_1;
output reg led_2, //led_2;
output reg[7:0]x_c1, //数码管1字模,个位;
output reg[7:0]x_c2, //数码管2字模,十位;
output reg[7:0]x_c3, //数码管3字模,百位;
output reg[7:0]x_c4 //数码管4字模,千位;
);
/**************************************************/ //1.分频;
reg[24:0] num; //num计数器;
reg num1; //秒脉冲;
reg num2; //按键脉冲;
always@(posedge clk or negedge res)
begin
if(~res)
begin
num <=0;
num1 <=0;
num2 <=0;
led_1 <=0;
led_2 <=0;
end
else
begin
if(num ==24_000_000 -1)
begin
num <=0;
num1 <=1;
led_1 <= ~led_1;
led_2 <= ~led_2;
end
else
begin
num <=num +1;
if(num ==10)
begin
num2 <=1;
end
else
begin
num2 <=0;
end

num1 <=0;
end
end

end
/**************************************************/ //2.计时;
reg[7:0] shi; //时
reg[7:0] fen; //分
reg[7:0] miao; //秒
always@(posedge clk or negedge res)
begin
if(~res)
begin
shi <= 8'b0001_0010; //12:00
fen <= 0;
miao <= 0;
end
else
begin
if(num1)
begin
/**************************************************/ //秒进位
if(miao[7:4] == 4'd5 && miao[3:0] == 4'd9)
begin
miao <= 8'd0;
/**************************************************/ //分进位
if(fen[7:4] == 4'd5 && fen[3:0] == 4'd9)
begin
fen <= 8'd0;
/**************************************************/ //时进位
if(shi[7:4] == 4'd2 && shi[3:0] == 4'd4)
begin
shi <=8'd0;
end
else if(shi[3:0] == 4'd9 )
begin
shi <={shi[7:4] +4'd1,shi[3:0] <= 4'd0};
end
else
begin
shi <= shi +8'd1;
end
/**************************************************/
end
else if(fen[3:0] == 4'd9)
begin
fen <={fen[7:4] + 4'd1,4'd0};
end
else
begin
fen <= fen +8'd1;
end
/**************************************************/
end
else if(miao[3:0] == 4'd9)
begin
miao <= {miao[7:4] + 4'd1,4'd0};
end
else
begin
miao <= miao + 8'd1;
end
/**************************************************/
end
/**************************************************/ //按键
if(num2 == 1)
begin
if(k_jian == 0) //小时加
begin
if((shi[7:4] == 4'd2) && (shi[3:0] == 4'd4)) //24小时
begin
shi <= 8'd0;
end
else if(shi[3:0] == 8'd9)
begin
shi <= {shi[7:4] + 4'd1,4'd0};
end
else
begin
shi <= shi + 8'd1;
end
end
/**************************************************/
if(k_jia == 0) //分钟加
begin
if((fen[7:4] == 4'd5) && (fen[3:0] == 4'd9)) //59分钟
begin
fen <= 8'd0;
//shi <= shi + 4'd1;
end
else if(fen[3:0] == 8'd9)
begin
fen <= {fen[7:4] + 4'd1,4'd0};
end
else
begin
fen <=fen + 8'd1;
end

end
/**************************************************/
if(k_ent == 0) //分钟减
begin
if((fen[7:4] == 4'd0) && (fen[3:0] == 4'd0))
begin
fen <= {4'd5,4'd9};
end
else if((fen[7:4] > 4'd0) && (fen[3:0] == 4'd0))
begin
fen <= {fen[7:4] - 4'd1,4'd9};
end
else
begin
fen <=fen - 8'd1;
end
end
/**************************************************/
end
/**************************************************/
end
end


/**************************************************/ //3.显示;
reg[3:0] x_b1; //数码管1数字,个位;
reg[3:0] x_b2; //数码管2数字,十位;
reg[3:0] x_b3; //数码管3数字,百位;
reg[3:0] x_b4; //数码管4数字,千位;
/**************************************************/
parameter seg_0 =8'hc0, //0
seg_1 =8'hf9, //1
seg_2 =8'ha4, //2
seg_3 =8'hb0, //3
seg_4 =8'h99, //4
seg_5 =8'h92, //5
seg_6 =8'h82, //6
seg_7 =8'hf8, //7
seg_8 =8'h80, //8
seg_9 =8'h90, //9
seg_A =8'h88, //A
seg_B =8'h83, //B
seg_C =8'hc6, //C
seg_D =8'ha1, //D
seg_E =8'h86, //E
seg_F =8'h8e, //F
seg_off =8'hff; //熄灭
/**************************************************/
always@(posedge clk or negedge res)
begin
if(~res)
begin
x_b1 <=4'd0;
x_b2 <=4'd0;
x_b3 <=4'd0;
x_b4 <=4'd0;
x_c1 <='b1001_1001; //4;
x_c2 <='b1011_0000; //3;
x_c3 <='b1010_0100; //2;
x_c4 <='b1111_1001; //1;
end
else
begin
if(num1) //秒脉冲
begin

x_b1 <=fen[3:0];
x_b2 <=fen[7:4];
x_b3 <=shi[3:0];
x_b4 <=shi[7:4];

/**************************************************/
case(x_b1) //个位;
0: x_c1 = seg_0; // 0
1: x_c1 = seg_1; // 1
2: x_c1 = seg_2; // 2
3: x_c1 = seg_3; // 3
4: x_c1 = seg_4; // 4
5: x_c1 = seg_5; // 5
6: x_c1 = seg_6; // 6
7: x_c1 = seg_7; // 7
8: x_c1 = seg_8; // 8
9: x_c1 = seg_9; // 9
10: x_c1 = seg_A; // A
11: x_c1 = seg_B; // B
12: x_c1 = seg_C; // C
13: x_c1 = seg_D; // D
14: x_c1 = seg_E; // E
15: x_c1 = seg_F; // F
default: x_c1 = seg_off; // 不显
endcase
/**************************************************/
case(x_b2) //十位;
0: x_c2 = seg_0; // 0
1: x_c2 = seg_1; // 1
2: x_c2 = seg_2; // 2
3: x_c2 = seg_3; // 3
4: x_c2 = seg_4; // 4
5: x_c2 = seg_5; // 5
6: x_c2 = seg_6; // 6
7: x_c2 = seg_7; // 7
8: x_c2 = seg_8; // 8
9: x_c2 = seg_9; // 9
10: x_c2 = seg_A; // A
11: x_c2 = seg_B; // B
12: x_c2 = seg_C; // C
13: x_c2 = seg_D; // D
14: x_c2 = seg_E; // E
15: x_c2 = seg_F; // F
default: x_c2 = seg_off; // 不显
endcase
/**************************************************/
case(x_b3) //百位
0: x_c3 = seg_0; // 0
1: x_c3 = seg_1; // 1
2: x_c3 = seg_2; // 2
3: x_c3 = seg_3; // 3
4: x_c3 = seg_4; // 4
5: x_c3 = seg_5; // 5
6: x_c3 = seg_6; // 6
7: x_c3 = seg_7; // 7
8: x_c3 = seg_8; // 8
9: x_c3 = seg_9; // 9
10: x_c3 = seg_A; // A
11: x_c3 = seg_B; // B
12: x_c3 = seg_C; // C
13: x_c3 = seg_D; // D
14: x_c3 = seg_E; // E
15: x_c3 = seg_F; // F
default: x_c3 = seg_off; // 不显
endcase
/**************************************************/
case(x_b4) //千位
0: x_c4 = seg_0; // 0
1: x_c4 = seg_1; // 1
2: x_c4 = seg_2; // 2
3: x_c4 = seg_3; // 3
4: x_c4 = seg_4; // 4
5: x_c4 = seg_5; // 5
6: x_c4 = seg_6; // 6
7: x_c4 = seg_7; // 7
8: x_c4 = seg_8; // 8
9: x_c4 = seg_9; // 9
10: x_c4 = seg_A; // A
11: x_c4 = seg_B; // B
12: x_c4 = seg_C; // C
13: x_c4 = seg_D; // D
14: x_c4 = seg_E; // E
15: x_c4 = seg_F; // F
default: x_c4 = seg_off; // 不显
endcase
/**************************************************/
end
end
end
/**************************************************/
endmodule
/**************************************************/
 

Offline suzhimingTopic starter

  • Contributor
  • !
  • Posts: 46
  • Country: cn
Re: Learn FPGA from scratch
« Reply #49 on: October 27, 2025, 02:20:28 pm »
dual-pulse signal generator
The minimum selection is 2, with a main frequency using a 100 MHz crystal oscillator, and 100/4 = 25 MHz.

Code: [Select]
/****************脉冲发生器**************************/
/****************EPM240****************************/
/****************ID:共同学习FPGA********************/
/****************20251006**************************/


module maichongfashengqi
(
input clk, //系统时钟50MHz;
input res, //复位信号,低电平有效;
input k_jia, //加;
input k_jian, //减;
input k_ent, //确认;
output reg led_1, //led_1;
output reg led_2, //led_2;
output pin1,
output pin2,
output pin3,
output pin4,

output reg[7:0]x_c1, //数码管1字模,个位;
output reg[7:0]x_c2, //数码管2字模,十位;
output reg[7:0]x_c3, //数码管3字模,百位;
output reg[7:0]x_c4 //数码管4字模,千位;
);
/**************************************************/ //主逻辑处理
reg maichong; //脉冲;
reg[1:0] state; //状态机寄存器4种状态;
reg[3:0] x_a1; //第四位;
reg[7:0] x_a2; //第三二一位;
reg[7:0] m_gao; //脉冲高;
reg[7:0] m_di; //脉冲低;
reg[7:0] m_chongfu; //脉冲重复次数;
reg[7:0] m_zhixing; //脉冲执行次数;

reg zx; //执行标志位
reg[7:0] zx_gao; //执行脉冲高;
reg[7:0] zx_di; //执行脉冲低;
reg[7:0] zx_chongfu; //执行重复;

assign pin1 = maichong;
assign pin2 = maichong;
assign pin3 = maichong;
assign pin4 = maichong;

always@(posedge clk or negedge res)
begin
if(~ res)
begin
led_1 <= 0;
led_2 <= 0;
state <= 0;
x_a1 <= 0;
x_a2 <= 0;
//m_gao <= 6;
if(m_gao == 0) begin m_gao <= 5; end
else begin m_gao <=m_gao; end //上次值
m_di <= 0;
m_chongfu <= 2;
m_zhixing <= 0;

zx <=0;
zx_gao <=0;
zx_di <=0;
zx_chongfu <=0;
maichong <=0;
end
else
begin
/**************************************************/
//if(m_gao == 0) begin m_gao <= 5; end //初始值5
case(state)
0: //高脉冲时间;
begin
x_a1 <= 1;
x_a2 <=m_gao;
led_1 <= 1'b0;
led_2 <= 1'b1;
if(kent_flag) begin state <= 1; m_di <= m_gao; end
if(num1 && (~k_jia)) begin m_gao <=m_gao +1; end
if(num1 && (~k_jian)) begin m_gao <=m_gao -1; end
//if(m_gao == 0) begin m_gao <= 5; end //初始值5
end
1: //低脉冲时间
begin
x_a1 <= 2;
x_a2 <=m_di;
led_1 <= 1'b1;
led_2 <= 1'b0;
if(kent_flag) begin state <= 2; end
if(num1 && (~k_jia)) begin m_di <=m_di +1; end
if(num1 && (~k_jian)) begin m_di <=m_di -1; end
end
2: //重复次数
begin
x_a1 <= 3;
x_a2 <=m_chongfu;
led_1 <= 1'b0;
led_2 <= 1'b0;
if(kent_flag) begin state<=3; end
if(num1 && (~k_jia)) begin m_chongfu <=m_chongfu +1; end
if(num1 && (~k_jian)) begin m_chongfu <=m_chongfu -1; end
end

3: //脉冲输出
begin
x_a1 <= 4;
x_a2 <= m_zhixing;
// led_1 <= 1'b1;
// led_2 <= 1'b1;
if(num1) begin led_2 <= ~led_2; end //led_2闪烁
if(kent_flag && !zx) //未执行时响应确认键;
begin
m_zhixing <= m_zhixing +1; //执行次数;
zx <= 1; //执行标志位;
zx_gao <= m_gao; //加载高电平计数;
zx_di <= m_di; //加载低电平计数;
zx_chongfu <= m_chongfu; //加载重复次数;
end
/**************************************************/
if(zx)
begin
/**************************************************/
if(zx_chongfu > 0) //重复次数
begin
/**************************************************/
if(zx_gao > 0) //高电平阶段
begin
maichong <= 1'b1;
zx_gao <= zx_gao - 1;
if(zx_gao == 1) //提前准备低电平;
begin
zx_di <= m_di;
end
end
/**************************************************/
else if (zx_di > 0) //低电平阶段
begin
led_1 <= ~led_1;
maichong <= 1'b0;
zx_di <= zx_di - 1;
if(zx_di == 1) //提前准备高电平;
begin
zx_chongfu <= zx_chongfu -1;
zx_gao <= m_gao;
end
end 
/**************************************************/
end
/**************************************************/
else // 所有重复完成,结束执行
begin
zx <= 0;
maichong <= 1'b0;
led_1 <= ~led_1;
end
/**************************************************/
end
/**************************************************/
end
endcase
/**************************************************/
end
end
/**************************************************/ //按键;
reg kjia_flag; //按键加标志位;
reg kjian_flag; //按键减标志位;
reg kent_flag; //按键确定标志位;
reg kjia_prev; //加上一次按键状态;
reg kjian_prev; //减上一次按键状态;
reg kent_prev; //确定上一次按键状态;


always@(posedge clk or negedge res)
begin
if(~ res)
begin
kent_flag <= 1'b0; //未按下
kent_prev <= 1'b0; //无按键
// kjia_prev <= 1'b0;
// kjia_flag <= 1'b0;
// kjian_prev <= 1'b0;
// kjian_flag <= 1'b0;

end
else
begin
kent_prev <= ~k_ent; //记住上一次状态
kent_flag <= kent_prev && k_ent; //松手以后按键标志位置一

// kjia_prev <= ~k_jia;
// kjia_flag <= kjia_prev && k_jia;

// kjian_prev <= ~k_jian;
// kjian_flag <= kjian_prev && k_jian;
end
end
/**************************************************/ //秒脉冲生成
reg[23:0] num; //num计数器;
reg num1; //秒脉冲;
always@(posedge clk or negedge res)
begin
if(~ res)
begin
num <= 0;
num1 <= 0;
end
else
begin
num <=num +1;
if(num ==15_000_000)
begin
num <= 0;
num1 <= 1;
end
else
begin
num1 <= 0;
end
end
end
/**************************************************/ //显示;
reg[3:0] x_b1; //数码管1数字,个位;
reg[3:0] x_b2; //数码管2数字,十位;
reg[3:0] x_b3; //数码管3数字,百位;
reg[3:0] x_b4; //数码管4数字,千位;
/**************************************************/
parameter seg_0 =8'hc0, //0
seg_1 =8'hf9, //1
seg_2 =8'ha4, //2
seg_3 =8'hb0, //3
seg_4 =8'h99, //4
seg_5 =8'h92, //5
seg_6 =8'h82, //6
seg_7 =8'hf8, //7
seg_8 =8'h80, //8
seg_9 =8'h90, //9
seg_A =8'h88, //A
seg_B =8'h83, //B
seg_C =8'hc6, //C
seg_D =8'ha1, //D
seg_E =8'h86, //E
seg_F =8'h8e, //F
seg_off =8'hff; //熄灭
/**************************************************/
always@(posedge clk or negedge res)
begin
if(~res)
begin
x_b1 <=4'd0;
x_b2 <=4'd0;
x_b3 <=4'd0;
x_b4 <=4'd0;
x_c1 <='b1001_1001; //4;
x_c2 <='b1011_0000; //3;
x_c3 <='b1010_0100; //2;
x_c4 <='b1111_1001; //1;
end
else
begin
x_b1 <=x_a2[3:0];
x_b2 <=x_a2[7:4];
//x_b3 <=x_a2[11:8];
x_b4 <=x_a1;

/**************************************************/
case(x_b1) //个位;
0: x_c1 = seg_0; // 0
1: x_c1 = seg_1; // 1
2: x_c1 = seg_2; // 2
3: x_c1 = seg_3; // 3
4: x_c1 = seg_4; // 4
5: x_c1 = seg_5; // 5
6: x_c1 = seg_6; // 6
7: x_c1 = seg_7; // 7
8: x_c1 = seg_8; // 8
9: x_c1 = seg_9; // 9
10: x_c1 = seg_A; // A
11: x_c1 = seg_B; // B
12: x_c1 = seg_C; // C
13: x_c1 = seg_D; // D
14: x_c1 = seg_E; // E
15: x_c1 = seg_F; // F
default: x_c1 = seg_off; // 不显
endcase
/**************************************************/
case(x_b2) //十位;
0: x_c2 = seg_0; // 0
1: x_c2 = seg_1; // 1
2: x_c2 = seg_2; // 2
3: x_c2 = seg_3; // 3
4: x_c2 = seg_4; // 4
5: x_c2 = seg_5; // 5
6: x_c2 = seg_6; // 6
7: x_c2 = seg_7; // 7
8: x_c2 = seg_8; // 8
9: x_c2 = seg_9; // 9
10: x_c2 = seg_A; // A
11: x_c2 = seg_B; // B
12: x_c2 = seg_C; // C
13: x_c2 = seg_D; // D
14: x_c2 = seg_E; // E
15: x_c2 = seg_F; // F
default: x_c2 = seg_off; // 不显
endcase
/**************************************************/
//case(x_b3) //百位
// 0: x_c3 = seg_0; // 0
// 1: x_c3 = seg_1; // 1
// 2: x_c3 = seg_2; // 2
// 3: x_c3 = seg_3; // 3
// 4: x_c3 = seg_4; // 4
// 5: x_c3 = seg_5; // 5
// 6: x_c3 = seg_6; // 6
// 7: x_c3 = seg_7; // 7
// 8: x_c3 = seg_8; // 8
// 9: x_c3 = seg_9; // 9
// 10: x_c3 = seg_A; // A
// 11: x_c3 = seg_B; // B
// 12: x_c3 = seg_C; // C
// 13: x_c3 = seg_D; // D
// 14: x_c3 = seg_E; // E
// 15: x_c3 = seg_F; // F
//default: x_c3 = seg_off; // 不显
//endcase
x_c3 = seg_off;
/**************************************************/
case(x_b4) //千位
0: x_c4 = seg_0; // 0
1: x_c4 = seg_1; // 1
2: x_c4 = seg_2; // 2
3: x_c4 = seg_3; // 3
4: x_c4 = seg_4; // 4
5: x_c4 = seg_5; // 5
6: x_c4 = seg_6; // 6
7: x_c4 = seg_7; // 7
8: x_c4 = seg_8; // 8
9: x_c4 = seg_9; // 9
10: x_c4 = seg_A; // A
11: x_c4 = seg_B; // B
12: x_c4 = seg_C; // C
13: x_c4 = seg_D; // D
14: x_c4 = seg_E; // E
15: x_c4 = seg_F; // F
default: x_c4 = seg_off; // 不显
endcase
/**************************************************/
end
end
/**************************************************/
endmodule
/**************************************************/
/**************************************************/
/**************************************************/
/**************************************************/[attachimg=1]
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf