我是同时做过FPGA开发(verilog)与ARM(c)开发,有很多人说学了单片机再学习FPGA会比较好过度。理由是单片机的C语言与FPGA的verilog语言很像。我不太赞成这一个说法,理由是:单片机的C语言是串行执行的,FPGA的verilog是并行执行的。虽然两者看上去语法差不多,但是语言所代表的含义完全不同。C语言最终到芯片中后是二进制代码,verilog语言最终到芯片是电路。举个例子,同样实现两个led灯的闪烁,一个是10hz,一个是5hz。
/********************************************************************************************************************************/
void isr(void){//1ms的中断
static u32 cnt_led1,cnt_led2;
cnt_led1++;
cnt_led2++;
if(cnt_led1>=50)
{
LED1=~LED1;
cnt_led1=0;
}
if(cnt_led2>=100)
{
LED2=~LED2;
cnt_led2=0;
}
}
int main(void)
{
INIT_LED();
INIT_ISR();
while(1)
{
}
}
/**********************************************************************************************************************************/
module LED(
CLK,
LED1,
LED2
);
input wire CLK;
output reg LED1=0;
output reg LED2=0;
reg [31:0]cnt1=0;
reg [31:0]cnt2=0;
always@(posedge CLK)//在时钟上升沿干的事情1
begin
if(cnt1<50*1000*50)begin
cnt1<=cnt1+1;
end
else begin
LED1<=~LED1;
cnt1<=0;
end
end
always@(posedge CLK)//在时钟上升沿干的事情2
begin
if(cnt2<50*1000*100)begin
cnt2<=cnt2+1;
end
else begin
LED2<=~LED2;
cnt2<=0;
end
end
endmodule
/**********************************************************************************************************************************/
可以发现,单片机实现两个“任务”可以用定时器中断实现,本质意义上来说是串行执行。
FPGA实现两个“任务”可以用时钟上升沿触发,而且一个时钟上升沿可以触发多个“任务”。
/**********************************************************************************************************************************/
再举个例子,输出3路12bit的DAC。
/********************************************************************************************/
unsigned int get_dac1;
unsigned int get_dac2;
unsigned int get_dac3;
int main(void)
{
DAC_INIT();
while(1){
*((unsigned int *)DAC1)=get_dac1&0x3ff;//第一步
*((unsigned int *)DAC2)=get_dac2&0x3ff;//第二步
*((unsigned int *)DAC3)=get_dac3&0x3ff;//第三步
}
}
/********************************************************************************************/
module OUT_DAC(
CLK,
DAC1,
DAC2,
DAC3,
BUFF_DAC1,
BUFF_DAC2,
BUFF_DAC3
);
input wire [11:0]BUFF_DAC1;
input wire [11:0]BUFF_DAC2;
input wire [11:0]BUFF_DAC3;
output reg [11:0]DAC1;
output reg [11:0]DAC2;
output reg [11:0]DAC3;
always@(posedge CLK)
begin
DAC1<=BUFF_DAC1;//第一步
DAC2<=BUFF_DAC2;//与上一步是同时执行
DAC3<=BUFF_DAC3;//与上一步是同时执行
end
endmodule
/********************************************************************************************/
从上面的例子我们可以得到:ARM的3个DAC输出是有先后的,FPGA的3个DAC输出是没有先后的。
所以我们常常听到别人说,FPGA比ARM运行速度“快”!
/********************************************************************************************/