【Sipeed 高云GW2A FPGA开发板】——Sipeed官网Tang-Primer-20K开发板例程学习
[复制链接]
本帖最后由 mars4zhu 于 2022-11-22 01:35 编辑
3. Tang-Primer-20K_Examples_Notes
3.1. assign-led-on
按照Sipeed网站的例程说明一步步进行,初次没有注意,看到有6个LED灯,就直接在verilog中编写了6个LED的assign语句。
module assign_led_on(
output wire [5:0] led_voltage_level
);
assign led_voltage_level = 6'b010101 ;
endmodule
综合通过,约束时也按照原理图给予对应的IO约束说明。
IO_LOC "led_voltage_level[5]" L16;
IO_PORT "led_voltage_level[5]" PULL_MODE=UP DRIVE=8;
IO_LOC "led_voltage_level[4]" L14;
IO_PORT "led_voltage_level[4]" PULL_MODE=UP DRIVE=8;
IO_LOC "led_voltage_level[3]" N14;
IO_PORT "led_voltage_level[3]" PULL_MODE=UP DRIVE=8;
IO_LOC "led_voltage_level[2]" N16;
IO_PORT "led_voltage_level[2]" PULL_MODE=UP DRIVE=8;
IO_LOC "led_voltage_level[1]" A13;
IO_PORT "led_voltage_level[1]" PULL_MODE=UP DRIVE=8;
IO_LOC "led_voltage_level[0]" C13;
IO_PORT "led_voltage_level[0]" PULL_MODE=UP DRIVE=8;
但是布局布线阶段报错,错误信息提示led_voltage_level[0]/led_voltage_level[1]约束中指定的两个引脚是专用引脚,不能被放置到该引脚。
ERROR (PR2028) : The constrained location is useless in current package
ERROR (PR2017) : 'led_voltage_level[1]' cannot be placed according to constraint, for the location is a dedicated pin (READY)
ERROR (PR2028) : The constrained location is useless in current package
ERROR (PR2017) : 'led_voltage_level[0]' cannot be placed according to constraint, for the location is a dedicated pin (DONE)
仔细一看,原来这两个引脚是FPGA的配置相关引脚,再细看之后发现,这两个引脚是双功能引脚,既可以用于配置的DONE和READY信号,也可以用于常规IO,需要在Project->Configuration中设置如下:
然后再进行布局布线,即可通过并生成正确的FPGA配置的bitstream位流文件。
之后即按照教程的流程完成配置下载即可。
实际运行后跟verilog代码预期效果符合,即1/3/5号LED灯点亮,效果如图:
PS: Gowin的开发环境GOWIN FPGA Designer,综合、布局布线的速度也太快了吧,基本就是几秒钟完成了从综合-布局-布线-时序分析-功耗分析-生成位流的全流程,让一直用Quartus、Vivado的人完全没反应过来。
PS1: 注意到双功能引脚的设置窗口中,也可以把JTAG、SSPI、MSPI等功能引脚设置成常规IO引脚,尤其是JTAG,一旦被配置为常规IO并且写入Flash,那么在上电-加载到FPGA-运行后,JTAG功能将不再可用,此时JTAG调试器无法发现FPGA芯片,配置/下载、调试功能均失效,需要按照教程中的“常见问题”的解决方案(https://wiki.sipeed.com/hardware/zh/tang/tang-primer-20k/examples/assign_led.html#%E6%88%90%E5%8A%9F%E7%83%A7%E5%BD%95%E8%BF%87%E4%B8%80%E6%AC%A1%E5%A4%96%E9%83%A8-Flash-%E5%90%8E-Programmer-%E8%BD%AF%E4%BB%B6%E6%97%A0%E6%B3%95%E5%86%8D%E7%83%A7%E5%BD%95),即短接FLASH引脚,使得FPGA无法正常加载Flash中的配置文件,此时FPGA的JTAG功能正常,从而再次进行配置/下载、调试功能。
3.2. key-led-on
3.2.1. 官网例程代码错误
按照教程设置,发现代码下载后运行,按键时LED并没有按照预期的随之点亮,仔细查看各项设置,跟例程说明的对比无差别,最后发现例程代码有问题,源代码如下:
module key_led_on(
input key,
output [5:4] led
);
assign led[1:0] = {2{key}};
endmodule
截图为证:
该代码在Tools->Schematic Viewer查看器中,显示LED与key之间毫无联系,如图:
3.2.2. 修改verilog代码
module key_led_on(
input key,
output [5:4] led
);
assign led[5:4] = {2{key}};
endmodule
修改后的代码,在Tools->Schematic Viewer中显示如下:
最后运行效果才达到跟网站例程的一样的效果。
3.2.3. 进一步优化代码,每个key与每个led一一对应
为了实现key与led的一一对应,进一步优化代码,如下:
IO_LOC "led[5]" L16;
IO_PORT "led[5]" PULL_MODE=UP DRIVE=8;
IO_LOC "led[4]" L14;
IO_PORT "led[4]" PULL_MODE=UP DRIVE=8;
IO_LOC "led[3]" N14;
IO_PORT "led[3]" PULL_MODE=UP DRIVE=8;
IO_LOC "led[2]" N16;
IO_PORT "led[2]" PULL_MODE=UP DRIVE=8;
IO_LOC "led[1]" A13;
IO_PORT "led[1]" PULL_MODE=UP DRIVE=8;
IO_LOC "led[0]" C13;
IO_PORT "led[0]" PULL_MODE=UP DRIVE=8;
IO_LOC "key[4]" C7;
IO_PORT "key[4]" PULL_MODE=UP;
IO_LOC "key[3]" D7;
IO_PORT "key[3]" PULL_MODE=UP;
IO_LOC "key[2]" T2;
IO_PORT "key[2]" PULL_MODE=UP;
IO_LOC "key[1]" T3;
IO_PORT "key[1]" PULL_MODE=UP;
IO_LOC "key[0]" T10;
IO_PORT "key[0]" PULL_MODE=UP;
同时修改IO约束文件如下:
module key_led_on(
input wire [4:0] key,
output wire [5:0] led
);
assign led[4:0] = key[4:0];
assign led[5] = 1'b0;
endmodule
并且同样需要将对应的Project->Configuration设置窗口中,设置对应的SSPI、DONE、READY专用引脚为常规IO引脚。
运行效果如图:
PS: 在Programmer中,SRAM Program进行到中途,点击Cancel取消后,FPGA为复位待下载状态,不运行新代码,也不会运行原代码。
PS1:于2022-11-21在Sipeed-FPGA官方QQ群中,向管理员反馈该问题后,及时改正该问题,目前官网例程代码已改正。
3.3. decode-led-on
按照网站例程,即可。
3.4. blink-led
按照网站例程,即可。
3.5. flow-led(官网暂缺,自行补充)
内部实现一个计数寄存器,在输入时钟信号的上升沿加1,累加到27_000_000后归零,然后重新开始计数,如此往复。然后在每次累加到最高计数时,LED循环左移1位,verilog代码如下:
module flow_led (
input sys_clk,
input sys_nrst,
output [5:0] led
);
parameter COUNTER_MAX = (27_000_000-1);
reg [31:0] rCounter;
always @ (posedge sys_clk or negedge sys_nrst) begin
if (!sys_nrst) begin
rCounter <= 32'd0;
end
else begin
rCounter <= (rCounter >= COUNTER_MAX) ? 32'd0 : (rCounter + 32'd1);
end
end
// ============================
reg [7:0] rLED;
always @ (posedge sys_clk or negedge sys_nrst) begin
if (!sys_nrst)
rLED <= 8'b0000_0001;
else
rLED[7:0] <= (rCounter == COUNTER_MAX) ?
{rLED[6:0], rLED[7]} : rLED;
end
// ============================
assign led = ~rLED[5:0];
endmodule
IO约束文件如下:
IO_LOC "led[5]" L16;
IO_PORT "led[5]" PULL_MODE=UP DRIVE=8;
IO_LOC "led[4]" L14;
IO_PORT "led[4]" PULL_MODE=UP DRIVE=8;
IO_LOC "led[3]" N14;
IO_PORT "led[3]" PULL_MODE=UP DRIVE=8;
IO_LOC "led[2]" N16;
IO_PORT "led[2]" PULL_MODE=UP DRIVE=8;
IO_LOC "led[1]" A13;
IO_PORT "led[1]" PULL_MODE=UP DRIVE=8;
IO_LOC "led[0]" C13;
IO_PORT "led[0]" PULL_MODE=UP DRIVE=8;
IO_LOC "sys_nrst" T10;
IO_PORT "sys_nrst" PULL_MODE=UP;
IO_LOC "sys_clk" H11;
IO_PORT "sys_clk" PULL_MODE=UP;
需要在Project->Configuration中设置SSPI、DONE、READY专用引脚为常规IO引脚功能,如前所述,不再赘叙。
运行效果如图:
- PS:
-
-
循环左移: rLED[7:0] <= {rLED[6:0], rLED[7]}; 此代码运行后,LED循环流水灯。
-
补零左移: rLED[7:0] <= rLED << 1; 运行后,LED只有一次流水灯效果,溢出后全部熄灭。
|