原创 学习FPGA前3天

2010-10-9 15:53 2756 9 9 分类: FPGA/CPLD

       去年从同学那里要了一块FPGA的空板,最近没什么事,所以就按着电路图在淘宝上买了一些需要的元器件,主芯片是ALTERA的EP2C5Q208C8,4800个LE,对于我一个初学者足够了。


      焊完板子,我先测设了一下电源部分,3.3V和1.2V都正常,没有短路现象,然后用Quartus 8.0打开一个简单的例子(用verilog hdl 编写的,参考网上的),然后在网上找了一下Quartus 8.0的基本操作,竟然直接编译成功了,然后我将从淘宝上买的并口的ByteBlaster2连接上开发板,下载也成功了,板子看不出来什么现象,可能是由于程序功能或者管脚未配置的原因,但至少说明最小系统加JTAG功能好用。当时还不是特别明白AS下载方式和JTAG下载方式的区别。


      我不是特别喜欢看书,我喜欢直接实践,在实践中会有一些感性的体会,所以我先下载了一些Quartus 8.0的使用教程然后一步一步的操作,渐渐体会出每一步的作用是什么,对整个开发过程也有了一些实实在在的认识: 编写输入文件(包括hdl语言和图像符号等方式)------编译和综合(综合就是将行为的功能的描述转化为与或非门级的形式)------布局布线(好像还包括综合后的优化,去除一些综合后的冗余逻辑)-------生成编程文件---------时序分析。大概这就是一个工程开发的整个过程。


     在学习hdl时,我选择了Verilog HDL ,因为简单易懂,和C有些类似,关键是要体会HDL语言是硬件描述语言,最后设计的功能要转化为实在的电路,这里的关键是理解并行的概念,在Verilog模块中所有过程块(如inital块、always块)、连续赋值语句assign、实例引用都是并行工作的。同时在模块中还存在着一些顺序块,比如在begin---end间的语句(除非阻塞赋值)。这里我对于非阻塞和阻塞还是有些理解不好,以后慢慢深入吧。教材,我用的是《Verilog数字系统设计教材》,是国内比较好的教材,里面也有不少实例,便于实践。


     第一个Verilog程序: LED闪烁


     module LED (out1,out2,clock);     // 端口列表
        output out1,out2;                          // 端口类型定义
        input clock;
        reg out1,out2;                               // 输出都在定义为reg,我感觉好像reg像是定义了一个锁存器,  


                                                                // 输出的信号需要保持就应该用到锁存器,不知道对不对
        reg [25:0] counter;                       // 用于分频计数,全局时钟50M
  
       initial                                            
       begin
         out1 = 1;
         out2 = 0;
      end


     always @ (posedge clock)
       begin
         counter <= counter + 1;
         if(counter == 26'd25000000)  //25000000/50000000=0.5s
            begin
                out1 = ~ out1;
                out2 = ~ out2;
                counter <= 0;
            end
       end
 endmodule


   在这个模块中包括两个过程块,initial和always,它们是并行同时在仿真进入这个模块后开始执行的,只是initial只执行一次,而always一直在执行,不断判断着后面的条件是否满足。begin---end是个顺序块,感觉就像是{ }的作用,担任它还有更复杂的用法,比如加在begin后块名,还可以加参数,还可以用disable禁止一个顺序块。


    第一个程序我感觉最大的障碍有两个地方:


    1. 全局时钟         原来用单片机ARM系统的时钟直接连接到内核和片上外设,只需要从几个已有的时钟源选择再分频就可以了,可是FPGA则不同,它内部就像是一块白纸,除了电源的管脚,其他的管脚和内部电路都是没有硬链接的,所以在使用时,首先看你的硬件电路图,外部晶振连接到FPGA芯片的哪些CLK输入管脚上,然后在你的模块中将时钟源分配为这个CLK管脚,这个时钟就是你系统的全局时钟了,你的模块的执行就是在这个CLK的触发下进行的。


    2.  程序的固化   JTAG至少调试接口,将镜像文件(.sof文件)下载的芯片内部的RAM里运行,然后掉电就没了,如果要固化的话,在FPGA外部需要一个EPCS4的配置芯片,通过AS接口将程序(.pof文件)下载到EPCS4中,然后当上电是,FPGA自动从EPCS4中读取配置信息,然后执行,实现了程序的固化。


    第二个Verilog程序:  共阴数码管显示


  module shumaguan (LED,SHU,COM,CLK);
  input CLK;
  output [7:0] SHU;
  output [3:0] COM;
  output [3:0] LED;
  reg [7:0] SHU;
  reg [7:0] ZIMO[9:0];
  reg [3:0] index;
  reg [3:0] COM;
  reg [3:0] LED;
  reg [25:0] counter;
 
  initial
     begin
        SHU = 8'b11111100; // a b c d e f g h  //0
        COM = 4'b1111;     // com1 com2 com3 com4
        LED = 4'b0001; 
        ZIMO[0] =  8'b11111100;  //0
        ZIMO[1] =  8'b01100000;  //1
        ZIMO[2] =  8'b11011010;  //2
        ZIMO[3] =  8'b11110010;  //3
        ZIMO[4] =  8'b01100110;  //4
        ZIMO[5] =  8'b10110110;  //5
        ZIMO[6] =  8'b10111110;  //6
        ZIMO[7] =  8'b11100000;  //7
        ZIMO[8] =  8'b11111110;  //8
        ZIMO[9] =  8'b11100110;  //9
        index = 4'b0000;
     end
    
  always @ (posedge CLK)
      begin
         counter <= counter + 1;
         if(counter == 26'd15000000)   //15000000/50000000=0.3S
           begin
              counter <= 0;
              /* 
               //direct value
              case (SHU)    
                 8'b11111100: SHU <= 8'b01100000;  //0---1
                 8'b01100000: SHU <= 8'b11011010;  //1---2
                 8'b11011010: SHU <= 8'b11110010;  //2---3
                 8'b11110010: SHU <= 8'b01100110;  //3---4
                 8'b01100110: SHU <= 8'b10110110;  //4---5
                 8'b10110110: SHU <= 8'b10111110;  //5---6
                 8'b10111110: SHU <= 8'b11100000;  //6---7
                 8'b11100000: SHU <= 8'b11111110;  //7---8
                 8'b11111110: SHU <= 8'b11100110;  //8---9
                 8'b11100110: SHU <= 8'b11111100;  //9---0
                 default    : SHU <= 8'b11111100;  // 0
               endcase
               */
               /* */
               //index memory
               SHU <= ZIMO[index];
               index = index + 1;
               if (index == 10)
                   index <= 0;
               /* */
               case (LED)
                  4'b0001: LED <= 4'b0010;
                  4'b0010: LED <= 4'b0100;
                  4'b0100: LED <= 4'b1000;
                  4'b1000: LED <= 4'b0001;
                  default: LED <= 4'b0001;
               endcase            
                          
            end
           
      end
  endmodule
    和第一个程序基本思路差不多


这3天的收获很多,接下来打算再多花时间看看Verilog,然后开始各种通信接口的设计。
 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
9
关闭 站长推荐上一条 /3 下一条