项目概述
本项目是基于Lattice小脚丫XO-4000HC FPGA核心板以及相应的硬禾学堂电赛训练板,按照官方要求所实现的DDS任意波形发生器/本地控制,可产生1-20MHz,幅度0.1-1V可调的正弦波、方波、三角波、锯齿波。 基本硬件介绍:
本项目所使用的主要器件包括Lattice小脚丫XO-4000HC FPGA核心板以及相应的硬禾学堂电赛训练板,使用了基于3PD5651E(10-Bit, 50MSPS, CMOS模数变换器)芯片的DAC模块,显示模块使用的是基于ssd1306芯片的128x64的OLED屏幕。
要求/任务:
- 1个旋转编码器和2个按键控制参数的输入
- 通过128 * 64的OLED显示参数信息以及菜单
- FPGA连接10bit/120Msps的高速DAC模块
作品可完成指标:
- 通过板上的高速DAC(10bits/125Msps)配合FPGA内部DDS的逻辑,生成波形可调(正弦波、三角波、锯齿波、方波)、频率可调(DC-)、幅度可调的波形
- 生成模拟信号的频率范围为DC-20MHz,调节精度可为1Hz(在家由于设备条件限制也是为了更便于调节,最终版代码改成了100Hz步进)
- 生成模拟信号的幅度为1-1.0Vpp
- 可以在OLED上显示当前波形、频率以及幅度
- 利用板上旋转编码器能够对波形进行切换、进行参数调节
设计思路:
本作品采用FPGA驱动DAC模块实现DDS任意波形发生器,可以将要输出的波形数据(如正弦函数表或其他)预先存放在存储单元(如BlockRAM)中,然后在系统标准时钟频率下,按照一定的顺序从存储单元中读出波形数据,再进行D/A转换及低通滤波,就可以得到一定频率的输出波形。上述过程可使用HDL硬件描述语言对FPGA编程实现。
下面是该项目系统构成框图:
其中FPGA内部逻辑如图所示:
主要的verilog模块如图所示:
实物展示图与作品使用说明:通过旋转旋钮以改变参数,通过按压旋钮改变所修改的参数对象(即:波形、幅度、频率),后接示波器即可查看输出。
实物展示图
主要代码片段:
DDS:
module dds(
input sys_clk, //The clock rate is same to sample rate, and we set it to SAMPLE_RATE.
input sys_rst_n,
input [1:0] wave_type, //The 00:Cos wave;01:Square wave;10:Trig wave;11:Saw wave.
input [31:0] wave_freq,
output reg [9:0] wave_dac
);
wire [9:0] Cos_Dac;
wire [9:0] Square_Dac;
wire [9:0] Trig_Dac;
wire [9:0] Saw_Dac;
always@(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
wave_dac <= 10'd0;
end else begin
case(wave_type)
2'b00: wave_dac <= Cos_Dac;
2'b01: wave_dac <= Square_Dac;
2'b10: wave_dac <= Trig_Dac;
2'b11: wave_dac <= Saw_Dac;
endcase
end
end
//Cos wave
reg [27:0] dds_phase;
wire [27:0] dds_phase_add;
assign dds_phase_add = (wave_freq << 1) + (wave_freq >> 3) + (wave_freq >> 4) + (wave_freq >> 5) + (wave_freq >> 6) + (wave_freq >> 9) + (wave_freq >> 11) + (wave_freq >> 13);
//wave_freq*2.2369384765625(10.00111100101010);
always@(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
dds_phase <= 28'd0;
end else begin
dds_phase <= dds_phase + dds_phase_add;
end
end
lut u_lut(
.address(dds_phase[27:20]),
.cos(Cos_Dac)
);
//Square wave
assign Square_Dac = {10{dds_phase[27]}};
//Trig wave
assign Trig_Dac = dds_phase[27] ? ~dds_phase[26:17] : dds_phase[26:17];
//Saw wave
assign Saw_Dac = dds_phase[27:18];
endmodule
OLED:
module oled12864
(
input clk, //12MHz系统时钟
input rst_n, //系统复位,低有效
input [1:0] dis_type,
input [31:0] dis_freq,
input [3:0] dis_amp,
// input debug,
output reg oled_csn, //OLCD液晶屏使能
output reg oled_rst, //OLCD液晶屏复位
output reg oled_dcn, //OLCD数据指令控制
output reg oled_clk, //OLCD时钟信号
output reg oled_dat //OLCD数据信号
);
localparam INIT_DEPTH = 16'd23; //LCD初始化的命令的数量
localparam IDLE = 7'h1, MAIN = 7'h2, INIT = 7'h4, SCAN = 7'h8, WRITE = 7'h10, DELAY = 7'h20,CHINESE=7'h40;
localparam HIGH = 1'b1, LOW = 1'b0;
localparam DATA = 1'b1, CMD = 1'b0;
reg [7:0] cmd [22:0]; //The register of command
reg [39:0] mem [122:0]; //The register of ASCII memory
reg [127:0] mem_hanzi[16:0]; //The register of chinese chars memeory
reg [7:0] mem_hanzi_num; //The number of chinese chars to display
reg [7:0] y_p, x_ph, x_pl;
reg [(8*21-1):0] char; //The memory of ASCII chars to display
reg [7:0] num; //The number of ASCII chars to display
reg [7:0] char_reg; //The register of ASCII char to display
reg [4:0] cnt_main, cnt_init, cnt_scan, cnt_write;
reg [5:0] cnt_chinese;
reg [15:0] num_delay, cnt_delay, cnt;
reg [6:0] state, state_back;
reg [(3*8-1):0] dis_type_buff; //Typical: Sin,Squ,Trg,Saw
wire [(9*8-1):0] dis_freq_buff; //Typical: 20000 KHz
wire [(7*8-1):0] dis_amp_buff; //Typical: 0.1 Vpp
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
dis_type_buff <= "Sin";
end else begin
case(dis_type)
2'b00: dis_type_buff <= "Sin";
2'b01: dis_type_buff <= "Squ";
2'b10: dis_type_buff <= "Trg";
2'b11: dis_type_buff <= "Saw";
endcase
end
end
wire [3:0] dis_freq_unit;
wire [3:0] dis_freq_ten;
wire [3:0] dis_freq_hun;
wire [3:0] dis_freq_tho;
wire [3:0] dis_freq_t_tho;
wire [3:0] dis_freq_h_hun;
wire [3:0] dis_freq_M;
wire [3:0] dis_freq_t_M;
assign dis_freq_buff = {dis_freq_t_M,4'd0,dis_freq_M,4'd0,dis_freq_h_hun,4'd0,dis_freq_t_tho,4'd0,dis_freq_tho,4'd0,dis_freq_hun,"00 "};
bcd_8421 u_bcd_8421(
.sys_clk(clk), //系统时钟,频率50MHz
.sys_rst_n(rst_n), //复位信号,低电平有效
.data(dis_freq/1), //输入需要转换的数据
.unit(dis_freq_unit), //个位BCD码
.ten(dis_freq_ten), //十位BCD码
.hun(dis_freq_hun), //百位BCD码
.tho(dis_freq_tho), //千位BCD码
.t_tho(dis_freq_t_tho), //万位BCD码
.h_hun(dis_freq_h_hun),//十万位BCD码
.M(dis_freq_M),
.t_M(dis_freq_t_M)
);
assign dis_amp_buff = (dis_amp != 4'd10) ? {"0.",4'd0,dis_amp," Vpp"} : {"1.0 Vpp"};
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
cnt_main <= 1'b0; cnt_init <= 1'b0; cnt_scan <= 1'b0; cnt_write <= 1'b0;cnt_chinese <= 1'b0;
y_p <= 1'b0; x_ph <= 1'b0; x_pl <= 1'b0;
num <= 1'b0; char <= 1'b0; char_reg <= 1'b0;
num_delay <= 16'd5; cnt_delay <= 1'b0; cnt <= 1'b0;
oled_csn <= HIGH; oled_rst <= HIGH; oled_dcn <= CMD; oled_clk <= HIGH; oled_dat <= LOW;
state <= IDLE; state_back <= IDLE;
end else begin
case(state)
IDLE:begin
cnt_main <= 1'b0; cnt_init <= 1'b0; cnt_scan <= 1'b0; cnt_write <= 1'b0;
y_p <= 1'b0; x_ph <= 1'b0; x_pl <= 1'b0;
num <= 1'b0; char <= 1'b0; char_reg <= 1'b0;
num_delay <= 16'd5; cnt_delay <= 1'b0; cnt <= 1'b0;mem_hanzi_num<=8'd0;
oled_csn <= HIGH; oled_rst <= HIGH; oled_dcn <= CMD; oled_clk <= HIGH; oled_dat <= LOW;
state <= MAIN; state_back <= MAIN;
end
MAIN:begin
if(cnt_main >= 5'd15) cnt_main <= 5'd13;//接下来执行空操作,实现数据只刷新一次
else cnt_main <= cnt_main + 1'b1;
case(cnt_main) //MAIN状态
5'd0 : begin state <= INIT; end
5'd1 : begin y_p <= 8'hb0; x_ph <= 8'h10; x_pl <= 8'h00; num <= 5'd16; char <= " ";state <= SCAN; end
5'd2 : begin y_p <= 8'hb1; x_ph <= 8'h10; x_pl <= 8'h00; num <= 5'd16; char <= " ";state <= SCAN; end
5'd3 : begin y_p <= 8'hb2; x_ph <= 8'h10; x_pl <= 8'h00; num <= 5'd16; char <= " ";state <= SCAN; end
5'd4 : begin y_p <= 8'hb3; x_ph <= 8'h10; x_pl <= 8'h00; num <= 5'd16; char <= " ";state <= SCAN; end
5'd5 : begin y_p <= 8'hb4; x_ph <= 8'h10; x_pl <= 8'h00; num <= 5'd16; char <= " ";state <= SCAN; end
5'd6 : begin y_p <= 8'hb5; x_ph <= 8'h10; x_pl <= 8'h00; num <= 5'd16; char <= " ";state <= SCAN; end
5'd7 : begin y_p <= 8'hb6; x_ph <= 8'h10; x_pl <= 8'h00; num <= 5'd16; char <= " Hz";state <= SCAN; end
5'd8 : begin y_p <= 8'hb4; x_ph <= 8'h10; x_pl <= 8'h00; num <= 5'd16; char <= " ";state <= SCAN; end
5'd9 : begin y_p <= 8'hb2; x_ph <= 8'h00; x_pl <= 8'h08; num <= 5'd16; char <= "WAVE: ";state <= SCAN; end
5'd10: begin y_p <= 8'hb4; x_ph <= 8'h00; x_pl <= 8'h08; num <= 5'd16; char <= "FRE: ";state <= SCAN; end
5'd11: begin y_p <= 8'hb6; x_ph <= 8'h00; x_pl <= 8'h08; num <= 5'd16; char <= "AMP: ";state <= SCAN; end
5'd12: begin y_p <= 8'hb0; x_ph <= 8'h00; x_pl <= 8'h08; num <= 5'd16; char <= " DDS-LSY ";state <= SCAN; end
5'd13: begin y_p <= 8'hb2; x_ph <= 8'h12; x_pl <= 8'h08; num <= 5'd3; char <= dis_type_buff;state <= SCAN; end
5'd14: begin y_p <= 8'hb4; x_ph <= 8'h12; x_pl <= 8'h08; num <= 5'd10; char <= dis_freq_buff;state <= SCAN; end
5'd15: begin y_p <= 8'hb6; x_ph <= 8'h12; x_pl <= 8'h08; num <= 5'd7; char <= dis_amp_buff;state <= SCAN; end
default: state <= IDLE; //如果你需要动态刷新一些信息,此行应该取消注释
endcase
end
INIT:begin //初始化状态
case(cnt_init)
5'd0: begin oled_rst <= LOW; cnt_init <= cnt_init + 1'b1; end //复位有效
5'd1: begin num_delay <= 16'd25000; state <= DELAY; state_back <= INIT; cnt_init <= cnt_init + 1'b1; end //延时大于3us
5'd2: begin oled_rst <= HIGH; cnt_init <= cnt_init + 1'b1; end //复位恢复
5'd3: begin num_delay <= 16'd25000; state <= DELAY; state_back <= INIT; cnt_init <= cnt_init + 1'b1; end //延时大于220us
5'd4: begin
if(cnt>=INIT_DEPTH) begin //当25条指令及数据发出后,配置完成
cnt <= 1'b0;
cnt_init <= cnt_init + 1'b1;
end else begin
cnt <= cnt + 1'b1; num_delay <= 16'd5;
oled_dcn <= CMD; char_reg <= cmd[cnt]; state <= WRITE; state_back <= INIT;
end
end
5'd5: begin cnt_init <= 1'b0; state <= MAIN; end //初始化完成,返回MAIN状态
default: state <= IDLE;
endcase
end
SCAN:begin //刷屏状态,从RAM中读取数据刷屏
if(cnt_scan == 5'd11) begin
if(num) cnt_scan <= 5'd3;
else cnt_scan <= cnt_scan + 1'b1;
end
else if(cnt_scan == 5'd12) cnt_scan <= 1'b0;
else cnt_scan <= cnt_scan + 1'b1;
case(cnt_scan)
5'd 0: begin oled_dcn <= CMD; char_reg <= y_p; state <= WRITE; state_back <= SCAN; end //定位列页地址
5'd 1: begin oled_dcn <= CMD; char_reg <= x_pl; state <= WRITE; state_back <= SCAN; end //定位行地址低位
5'd 2: begin oled_dcn <= CMD; char_reg <= x_ph; state <= WRITE; state_back <= SCAN; end //定位行地址高位
5'd 3: begin num <= num - 1'b1;end
5'd 4: begin oled_dcn <= DATA; char_reg <= 8'h00; state <= WRITE; state_back <= SCAN; end //将5*8点阵编程8*8
5'd 5: begin oled_dcn <= DATA; char_reg <= 8'h00; state <= WRITE; state_back <= SCAN; end //将5*8点阵编程8*8
5'd 6: begin oled_dcn <= DATA; char_reg <= 8'h00; state <= WRITE; state_back <= SCAN; end //将5*8点阵编程8*8
5'd 7: begin oled_dcn <= DATA; char_reg <= mem[char[(num*8)+:8]][39:32]; state <= WRITE; state_back <= SCAN; end
5'd 8: begin oled_dcn <= DATA; char_reg <= mem[char[(num*8)+:8]][31:24]; state <= WRITE; state_back <= SCAN; end
5'd 9: begin oled_dcn <= DATA; char_reg <= mem[char[(num*8)+:8]][23:16]; state <= WRITE; state_back <= SCAN; end
5'd10: begin oled_dcn <= DATA; char_reg <= mem[char[(num*8)+:8]][15: 8]; state <= WRITE; state_back <= SCAN; end
5'd11: begin oled_dcn <= DATA; char_reg <= mem[char[(num*8)+:8]][ 7: 0]; state <= WRITE; state_back <= SCAN; end
5'd12: begin state <= MAIN; end
default: state <= IDLE;
endcase
end
CHINESE:begin //显示汉字
if(cnt_chinese == 6'd38) cnt_chinese <= 1'b0;
else cnt_chinese <= cnt_chinese+1'b1;
case(cnt_chinese)
6'd 0: begin oled_dcn <= CMD; char_reg <= y_p; state <= WRITE; state_back <= CHINESE; end //定位列页地址
6'd 1: begin oled_dcn <= CMD; char_reg <= x_pl; state <= WRITE; state_back <= CHINESE; end //定位行地址低位
6'd 2: begin oled_dcn <= CMD; char_reg <= x_ph; state <= WRITE; state_back <= CHINESE; end //定位行地址高位
6'd3 : begin oled_dcn <= DATA; char_reg <= mem_hanzi[mem_hanzi_num][127:120]; state <= WRITE; state_back <= CHINESE; end
6'd4 : begin oled_dcn <= DATA; char_reg <= mem_hanzi[mem_hanzi_num][119:112]; state <= WRITE; state_back <= CHINESE; end
6'd5 : begin oled_dcn <= DATA; char_reg <= mem_hanzi[mem_hanzi_num][111:104]; state <= WRITE; state_back <= CHINESE; end
6'd6 : begin oled_dcn <= DATA; char_reg <= mem_hanzi[mem_hanzi_num][103:96] ; state <= WRITE; state_back <= CHINESE; end
6'd7 : begin oled_dcn <= DATA; char_reg <= mem_hanzi[mem_hanzi_num][95:88] ; state <= WRITE; state_back <= CHINESE; end
6'd8 : begin oled_dcn <= DATA; char_reg <= mem_hanzi[mem_hanzi_num][87:80] ; state <= WRITE; state_back <= CHINESE; end
6'd9 : begin oled_dcn <= DATA; char_reg <= mem_hanzi[mem_hanzi_num][79:72] ; state <= WRITE; state_back <= CHINESE; end
6'd10: begin oled_dcn <= DATA; char_reg <= mem_hanzi[mem_hanzi_num][71:64] ; state <= WRITE; state_back <= CHINESE; end
6'd11: begin oled_dcn <= DATA; char_reg <= mem_hanzi[mem_hanzi_num][63:56]; state <= WRITE; state_back <= CHINESE; end
6'd12: begin oled_dcn <= DATA; char_reg <= mem_hanzi[mem_hanzi_num][55:48]; state <= WRITE; state_back <= CHINESE; end
6'd13: begin oled_dcn <= DATA; char_reg <= mem_hanzi[mem_hanzi_num][47:40]; state <= WRITE; state_back <= CHINESE; end
6'd14: begin oled_dcn <= DATA; char_reg <= mem_hanzi[mem_hanzi_num][39:32]; state <= WRITE; state_back <= CHINESE; end
6'd15: begin oled_dcn <= DATA; char_reg <= mem_hanzi[mem_hanzi_num][31:24]; state <= WRITE; state_back <= CHINESE; end
6'd16: begin oled_dcn <= DATA; char_reg <= mem_hanzi[mem_hanzi_num][23:16]; state <= WRITE; state_back <= CHINESE; end
6'd17: begin oled_dcn <= DATA; char_reg <= mem_hanzi[mem_hanzi_num][15: 8]; state <= WRITE; state_back <= CHINESE; end
6'd18: begin oled_dcn <= DATA; char_reg <= mem_hanzi[mem_hanzi_num][ 7: 0]; state <= WRITE; state_back <= CHINESE; end
6'd19: begin oled_dcn <= CMD; char_reg <= y_p+1; state <= WRITE; state_back <= CHINESE; end //定位列页地址
6'd20: begin oled_dcn <= CMD; char_reg <= x_pl; state <= WRITE; state_back <= CHINESE; end //定位行地址低位
6'd21: begin oled_dcn <= CMD; char_reg <= x_ph; state <= WRITE; state_back <= CHINESE; end //定位行地址高位
6'd22: begin oled_dcn <= DATA; char_reg <= mem_hanzi[mem_hanzi_num+1][127:120]; state <= WRITE; state_back <= CHINESE; end
6'd23: begin oled_dcn <= DATA; char_reg <= mem_hanzi[mem_hanzi_num+1][119:112]; state <= WRITE; state_back <= CHINESE; end
6'd24: begin oled_dcn <= DATA; char_reg <= mem_hanzi[mem_hanzi_num+1][111:104]; state <= WRITE; state_back <= CHINESE; end
6'd25: begin oled_dcn <= DATA; char_reg <= mem_hanzi[mem_hanzi_num+1][103:96] ; state <= WRITE; state_back <= CHINESE; end
6'd26: begin oled_dcn <= DATA; char_reg <= mem_hanzi[mem_hanzi_num+1][95:88] ; state <= WRITE; state_back <= CHINESE; end
6'd27: begin oled_dcn <= DATA; char_reg <= mem_hanzi[mem_hanzi_num+1][87:80] ; state <= WRITE; state_back <= CHINESE; end
6'd28: begin oled_dcn <= DATA; char_reg <= mem_hanzi[mem_hanzi_num+1][79:72] ; state <= WRITE; state_back <= CHINESE; end
6'd29: begin oled_dcn <= DATA; char_reg <= mem_hanzi[mem_hanzi_num+1][71:64] ; state <= WRITE; state_back <= CHINESE; end
6'd30: begin oled_dcn <= DATA; char_reg <= mem_hanzi[mem_hanzi_num+1][63:56]; state <= WRITE; state_back <= CHINESE; end
6'd31: begin oled_dcn <= DATA; char_reg <= mem_hanzi[mem_hanzi_num+1][55:48]; state <= WRITE; state_back <= CHINESE; end
6'd32: begin oled_dcn <= DATA; char_reg <= mem_hanzi[mem_hanzi_num+1][47:40]; state <= WRITE; state_back <= CHINESE; end
6'd33: begin oled_dcn <= DATA; char_reg <= mem_hanzi[mem_hanzi_num+1][39:32]; state <= WRITE; state_back <= CHINESE; end
6'd34: begin oled_dcn <= DATA; char_reg <= mem_hanzi[mem_hanzi_num+1][31:24]; state <= WRITE; state_back <= CHINESE; end
6'd35: begin oled_dcn <= DATA; char_reg <= mem_hanzi[mem_hanzi_num+1][23:16]; state <= WRITE; state_back <= CHINESE; end
6'd36: begin oled_dcn <= DATA; char_reg <= mem_hanzi[mem_hanzi_num+1][15: 8]; state <= WRITE; state_back <= CHINESE; end
6'd37: begin oled_dcn <= DATA; char_reg <= mem_hanzi[mem_hanzi_num+1][ 7: 0]; state <= WRITE; state_back <= CHINESE; end
6'd38: begin state <= MAIN; end
default: state <= IDLE;
endcase
end
WRITE:begin //WRITE状态,将数据按照SPI时序发送给屏幕
if(cnt_write >= 5'd17) cnt_write <= 1'b0;
else cnt_write <= cnt_write + 1'b1;
case(cnt_write)
5'd 0: begin oled_csn <= LOW; end //9位数据最高位为命令数据控制位
5'd 1: begin oled_clk <= LOW; oled_dat <= char_reg[7]; end //先发高位数据
5'd 2: begin oled_clk <= HIGH; end
5'd 3: begin oled_clk <= LOW; oled_dat <= char_reg[6]; end
5'd 4: begin oled_clk <= HIGH; end
5'd 5: begin oled_clk <= LOW; oled_dat <= char_reg[5]; end
5'd 6: begin oled_clk <= HIGH; end
5'd 7: begin oled_clk <= LOW; oled_dat <= char_reg[4]; end
5'd 8: begin oled_clk <= HIGH; end
5'd 9: begin oled_clk <= LOW; oled_dat <= char_reg[3]; end
5'd10: begin oled_clk <= HIGH; end
5'd11: begin oled_clk <= LOW; oled_dat <= char_reg[2]; end
5'd12: begin oled_clk <= HIGH; end
5'd13: begin oled_clk <= LOW; oled_dat <= char_reg[1]; end
5'd14: begin oled_clk <= HIGH; end
5'd15: begin oled_clk <= LOW; oled_dat <= char_reg[0]; end //后发低位数据
5'd16: begin oled_clk <= HIGH; end
5'd17: begin oled_csn <= HIGH; state <= DELAY; end //
default: state <= IDLE;
endcase
end
DELAY:begin //延时状态
if(cnt_delay >= num_delay) begin
cnt_delay <= 16'd0; state <= state_back;
end else cnt_delay <= cnt_delay + 1'b1;
end
default:state <= IDLE;
endcase
end
end
//OLED配置指令数据
always@(posedge rst_n)
begin
cmd[0 ] = {8'hae};
cmd[1 ] = {8'hd5};
cmd[2 ] = {8'h80};
cmd[3 ] = {8'ha8};
cmd[4 ] = {8'h3f};
cmd[5 ] = {8'hd3};
cmd[6 ] = {8'h00};
cmd[7 ] = {8'h40};
cmd[8 ] = {8'h8d};
cmd[9 ] = {8'h14};
cmd[10] = {8'h20};
cmd[11] = {8'h02};
cmd[12] = {8'hc8};
cmd[13] = {8'ha1};
cmd[14] = {8'hda};
cmd[15] = {8'h12};
cmd[16] = {8'h81};
cmd[17] = {8'hcf};
cmd[18] = {8'hd9};
cmd[19] = {8'hf1};
cmd[20] = {8'hdb};
cmd[21] = {8'h40};
cmd[22] = {8'haf};
end
//5*8点阵字库数据
always@(posedge rst_n)
begin
mem[ 0] = {8'h3E, 8'h51, 8'h49, 8'h45, 8'h3E}; // 48 0
mem[ 1] = {8'h00, 8'h42, 8'h7F, 8'h40, 8'h00}; // 49 1
mem[ 2] = {8'h42, 8'h61, 8'h51, 8'h49, 8'h46}; // 50 2
mem[ 3] = {8'h21, 8'h41, 8'h45, 8'h4B, 8'h31}; // 51 3
mem[ 4] = {8'h18, 8'h14, 8'h12, 8'h7F, 8'h10}; // 52 4
mem[ 5] = {8'h27, 8'h45, 8'h45, 8'h45, 8'h39}; // 53 5
mem[ 6] = {8'h3C, 8'h4A, 8'h49, 8'h49, 8'h30}; // 54 6
mem[ 7] = {8'h01, 8'h71, 8'h09, 8'h05, 8'h03}; // 55 7
mem[ 8] = {8'h36, 8'h49, 8'h49, 8'h49, 8'h36}; // 56 8
mem[ 9] = {8'h06, 8'h49, 8'h49, 8'h29, 8'h1E}; // 57 9
mem[ 10] = {8'h7C, 8'h12, 8'h11, 8'h12, 8'h7C}; // 65 A
mem[ 11] = {8'h7F, 8'h49, 8'h49, 8'h49, 8'h36}; // 66 B
mem[ 12] = {8'h3E, 8'h41, 8'h41, 8'h41, 8'h22}; // 67 C
mem[ 13] = {8'h7F, 8'h41, 8'h41, 8'h22, 8'h1C}; // 68 D
mem[ 14] = {8'h7F, 8'h49, 8'h49, 8'h49, 8'h41}; // 69 E
mem[ 15] = {8'h7F, 8'h09, 8'h09, 8'h09, 8'h01}; // 70 F
mem[ 32] = {8'h00, 8'h00, 8'h00, 8'h00, 8'h00}; // 32 sp
mem[ 33] = {8'h00, 8'h00, 8'h2f, 8'h00, 8'h00}; // 33 !
mem[ 34] = {8'h00, 8'h07, 8'h00, 8'h07, 8'h00}; // 34
mem[ 35] = {8'h14, 8'h7f, 8'h14, 8'h7f, 8'h14}; // 35 #
mem[ 36] = {8'h24, 8'h2a, 8'h7f, 8'h2a, 8'h12}; // 36 $
mem[ 37] = {8'h62, 8'h64, 8'h08, 8'h13, 8'h23}; // 37 %
mem[ 38] = {8'h36, 8'h49, 8'h55, 8'h22, 8'h50}; // 38 &
mem[ 39] = {8'h00, 8'h05, 8'h03, 8'h00, 8'h00}; // 39 '
mem[ 40] = {8'h00, 8'h1c, 8'h22, 8'h41, 8'h00}; // 40 (
mem[ 41] = {8'h00, 8'h41, 8'h22, 8'h1c, 8'h00}; // 41 )
mem[ 42] = {8'h14, 8'h08, 8'h3E, 8'h08, 8'h14}; // 42 *
mem[ 43] = {8'h08, 8'h08, 8'h3E, 8'h08, 8'h08}; // 43 +
mem[ 44] = {8'h00, 8'h00, 8'hA0, 8'h60, 8'h00}; // 44 ,
mem[ 45] = {8'h08, 8'h08, 8'h08, 8'h08, 8'h08}; // 45 -
mem[ 46] = {8'h00, 8'h60, 8'h60, 8'h00, 8'h00}; // 46 .
mem[ 47] = {8'h20, 8'h10, 8'h08, 8'h04, 8'h02}; // 47 /
mem[ 48] = {8'h3E, 8'h51, 8'h49, 8'h45, 8'h3E}; // 48 0
mem[ 49] = {8'h00, 8'h42, 8'h7F, 8'h40, 8'h00}; // 49 1
mem[ 50] = {8'h42, 8'h61, 8'h51, 8'h49, 8'h46}; // 50 2
mem[ 51] = {8'h21, 8'h41, 8'h45, 8'h4B, 8'h31}; // 51 3
mem[ 52] = {8'h18, 8'h14, 8'h12, 8'h7F, 8'h10}; // 52 4
mem[ 53] = {8'h27, 8'h45, 8'h45, 8'h45, 8'h39}; // 53 5
mem[ 54] = {8'h3C, 8'h4A, 8'h49, 8'h49, 8'h30}; // 54 6
mem[ 55] = {8'h01, 8'h71, 8'h09, 8'h05, 8'h03}; // 55 7
mem[ 56] = {8'h36, 8'h49, 8'h49, 8'h49, 8'h36}; // 56 8
mem[ 57] = {8'h06, 8'h49, 8'h49, 8'h29, 8'h1E}; // 57 9
mem[ 58] = {8'h00, 8'h36, 8'h36, 8'h00, 8'h00}; // 58 :
mem[ 59] = {8'h00, 8'h56, 8'h36, 8'h00, 8'h00}; // 59 ;
mem[ 60] = {8'h08, 8'h14, 8'h22, 8'h41, 8'h00}; // 60 <
mem[ 61] = {8'h14, 8'h14, 8'h14, 8'h14, 8'h14}; // 61 =
mem[ 62] = {8'h00, 8'h41, 8'h22, 8'h14, 8'h08}; // 62 >
mem[ 63] = {8'h02, 8'h01, 8'h51, 8'h09, 8'h06}; // 63 ?
mem[ 64] = {8'h32, 8'h49, 8'h59, 8'h51, 8'h3E}; // 64 @
mem[ 65] = {8'h7C, 8'h12, 8'h11, 8'h12, 8'h7C}; // 65 A
mem[ 66] = {8'h7F, 8'h49, 8'h49, 8'h49, 8'h36}; // 66 B
mem[ 67] = {8'h3E, 8'h41, 8'h41, 8'h41, 8'h22}; // 67 C
mem[ 68] = {8'h7F, 8'h41, 8'h41, 8'h22, 8'h1C}; // 68 D
mem[ 69] = {8'h7F, 8'h49, 8'h49, 8'h49, 8'h41}; // 69 E
mem[ 70] = {8'h7F, 8'h09, 8'h09, 8'h09, 8'h01}; // 70 F
mem[ 71] = {8'h3E, 8'h41, 8'h49, 8'h49, 8'h7A}; // 71 G
mem[ 72] = {8'h7F, 8'h08, 8'h08, 8'h08, 8'h7F}; // 72 H
mem[ 73] = {8'h00, 8'h41, 8'h7F, 8'h41, 8'h00}; // 73 I
mem[ 74] = {8'h20, 8'h40, 8'h41, 8'h3F, 8'h01}; // 74 J
mem[ 75] = {8'h7F, 8'h08, 8'h14, 8'h22, 8'h41}; // 75 K
mem[ 76] = {8'h7F, 8'h40, 8'h40, 8'h40, 8'h40}; // 76 L
mem[ 77] = {8'h7F, 8'h02, 8'h0C, 8'h02, 8'h7F}; // 77 M
mem[ 78] = {8'h7F, 8'h04, 8'h08, 8'h10, 8'h7F}; // 78 N
mem[ 79] = {8'h3E, 8'h41, 8'h41, 8'h41, 8'h3E}; // 79 O
mem[ 80] = {8'h7F, 8'h09, 8'h09, 8'h09, 8'h06}; // 80 P
mem[ 81] = {8'h3E, 8'h41, 8'h51, 8'h21, 8'h5E}; // 81 Q
mem[ 82] = {8'h7F, 8'h09, 8'h19, 8'h29, 8'h46}; // 82 R
mem[ 83] = {8'h46, 8'h49, 8'h49, 8'h49, 8'h31}; // 83 S
mem[ 84] = {8'h01, 8'h01, 8'h7F, 8'h01, 8'h01}; // 84 T
mem[ 85] = {8'h3F, 8'h40, 8'h40, 8'h40, 8'h3F}; // 85 U
mem[ 86] = {8'h1F, 8'h20, 8'h40, 8'h20, 8'h1F}; // 86 V
mem[ 87] = {8'h3F, 8'h40, 8'h38, 8'h40, 8'h3F}; // 87 W
mem[ 88] = {8'h63, 8'h14, 8'h08, 8'h14, 8'h63}; // 88 X
mem[ 89] = {8'h07, 8'h08, 8'h70, 8'h08, 8'h07}; // 89 Y
mem[ 90] = {8'h61, 8'h51, 8'h49, 8'h45, 8'h43}; // 90 Z
mem[ 91] = {8'h00, 8'h7F, 8'h41, 8'h41, 8'h00}; // 91 [
mem[ 92] = {8'h55, 8'h2A, 8'h55, 8'h2A, 8'h55}; // 92 .
mem[ 93] = {8'h00, 8'h41, 8'h41, 8'h7F, 8'h00}; // 93 ]
mem[ 94] = {8'h04, 8'h02, 8'h01, 8'h02, 8'h04}; // 94 ^
mem[ 95] = {8'h40, 8'h40, 8'h40, 8'h40, 8'h40}; // 95 _
mem[ 96] = {8'h00, 8'h01, 8'h02, 8'h04, 8'h00}; // 96 '
mem[ 97] = {8'h20, 8'h54, 8'h54, 8'h54, 8'h78}; // 97 a
mem[ 98] = {8'h7F, 8'h48, 8'h44, 8'h44, 8'h38}; // 98 b
mem[ 99] = {8'h38, 8'h44, 8'h44, 8'h44, 8'h20}; // 99 c
mem[100] = {8'h38, 8'h44, 8'h44, 8'h48, 8'h7F}; // 100 d
mem[101] = {8'h38, 8'h54, 8'h54, 8'h54, 8'h18}; // 101 e
mem[102] = {8'h08, 8'h7E, 8'h09, 8'h01, 8'h02}; // 102 f
mem[103] = {8'h18, 8'hA4, 8'hA4, 8'hA4, 8'h7C}; // 103 g
mem[104] = {8'h7F, 8'h08, 8'h04, 8'h04, 8'h78}; // 104 h
mem[105] = {8'h00, 8'h44, 8'h7D, 8'h40, 8'h00}; // 105 i
mem[106] = {8'h40, 8'h80, 8'h84, 8'h7D, 8'h00}; // 106 j
mem[107] = {8'h7F, 8'h10, 8'h28, 8'h44, 8'h00}; // 107 k
mem[108] = {8'h00, 8'h41, 8'h7F, 8'h40, 8'h00}; // 108 l
mem[109] = {8'h7C, 8'h04, 8'h18, 8'h04, 8'h78}; // 109 m
mem[110] = {8'h7C, 8'h08, 8'h04, 8'h04, 8'h78}; // 110 n
mem[111] = {8'h38, 8'h44, 8'h44, 8'h44, 8'h38}; // 111 o
mem[112] = {8'hFC, 8'h24, 8'h24, 8'h24, 8'h18}; // 112 p
mem[113] = {8'h18, 8'h24, 8'h24, 8'h18, 8'hFC}; // 113 q
mem[114] = {8'h7C, 8'h08, 8'h04, 8'h04, 8'h08}; // 114 r
mem[115] = {8'h48, 8'h54, 8'h54, 8'h54, 8'h20}; // 115 s
mem[116] = {8'h04, 8'h3F, 8'h44, 8'h40, 8'h20}; // 116 t
mem[117] = {8'h3C, 8'h40, 8'h40, 8'h20, 8'h7C}; // 117 u
mem[118] = {8'h1C, 8'h20, 8'h40, 8'h20, 8'h1C}; // 118 v
mem[119] = {8'h3C, 8'h40, 8'h30, 8'h40, 8'h3C}; // 119 w
mem[120] = {8'h44, 8'h28, 8'h10, 8'h28, 8'h44}; // 120 x
mem[121] = {8'h1C, 8'hA0, 8'hA0, 8'hA0, 8'h7C}; // 121 y
mem[122] = {8'h44, 8'h64, 8'h54, 8'h4C, 8'h44}; // 122 z
end
//16*16 汉字
always@(posedge rst_n)
begin
mem_hanzi[ 0 ] = {8'h04,8'h84,8'hE4,8'h5C,8'h44,8'hC4,8'h00,8'hF2,8'h92,8'h92,8'hFE,8'h92,8'h92,8'hF2,8'h02,8'h00};
mem_hanzi[ 1 ] = {8'h02,8'h01,8'h7F,8'h10,8'h10,8'h3F,8'h80,8'h8F,8'h54,8'h24,8'h5F,8'h44,8'h84,8'h87,8'h80,8'h00};//"硬",0
mem_hanzi[ 2 ] = {8'h00,8'h40,8'h44,8'h44,8'h44,8'h44,8'hC4,8'hFC,8'hC2,8'h42,8'h42,8'h43,8'h42,8'h40,8'h00,8'h00};
mem_hanzi[ 3 ] = {8'h20,8'h20,8'h10,8'h08,8'h04,8'h03,8'h00,8'hFF,8'h00,8'h03,8'h04,8'h08,8'h10,8'h20,8'h20,8'h00};//"禾",1
mem_hanzi[ 4 ] = {8'h40,8'h30,8'h11,8'h96,8'h90,8'h90,8'h91,8'h96,8'h90,8'h90,8'h98,8'h14,8'h13,8'h50,8'h30,8'h00};
mem_hanzi[ 5 ] = {8'h04,8'h04,8'h04,8'h04,8'h04,8'h44,8'h84,8'h7E,8'h06,8'h05,8'h04,8'h04,8'h04,8'h04,8'h04,8'h00};//"学",2
mem_hanzi[ 6 ] = {8'h20,8'h18,8'h08,8'hEA,8'h2C,8'h28,8'h28,8'h2F,8'h28,8'h28,8'h2C,8'hEA,8'h08,8'h28,8'h18,8'h00};
mem_hanzi[ 7 ] = {8'h40,8'h40,8'h48,8'h49,8'h49,8'h49,8'h49,8'h7F,8'h49,8'h49,8'h49,8'h49,8'h48,8'h40,8'h40,8'h00};//"堂",3
//此处可以导入需要的字模
end
/*汉字:硬禾学堂
以汉字“硬禾学堂”RAM生成步骤为例:
1、阴码、列行式、逆向 生成字模
2、然后把生成的字模作为RAM的元素
*/
endmodule
lut:
module lut(
input [7:0] address,
output reg [9:0] cos
);
wire [1:0] section;
reg [5:0] lut_address;
reg [8:0] lut_cos;
assign section = address[7:6]; //Get the sections of cos wave to reduce memory
always@(address)begin
case(section)
2'b00: begin
lut_address = address[5:0];
cos = 9'h1ff + lut_cos;
end
2'b01: begin
lut_address = ~address[5:0];
cos = 9'h1ff + lut_cos;
end
2'b10: begin
lut_address = address[5:0];
cos = 9'h1ff - lut_cos;
end
2'b11: begin
lut_address = ~address[5:0];
cos = 9'h1ff - lut_cos;
end
endcase
end
always @(lut_address) begin
case(lut_address)
6'h0: lut_cos=9'h0;
6'h1: lut_cos=9'hC;
6'h2: lut_cos=9'h19;
6'h3: lut_cos=9'h25;
6'h4: lut_cos=9'h32;
6'h5: lut_cos=9'h3E;
6'h6: lut_cos=9'h4B;
6'h7: lut_cos=9'h57;
6'h8: lut_cos=9'h63;
6'h9: lut_cos=9'h70;
6'ha: lut_cos=9'h7C;
6'hb: lut_cos=9'h88;
6'hc: lut_cos=9'h94;
6'hd: lut_cos=9'hA0;
6'he: lut_cos=9'hAC;
6'hf: lut_cos=9'hB8;
6'h10: lut_cos=9'hC3;
6'h11: lut_cos=9'hCF;
6'h12: lut_cos=9'hDA;
6'h13: lut_cos=9'hE6;
6'h14: lut_cos=9'hF1;
6'h15: lut_cos=9'hFC;
6'h16: lut_cos=9'h107;
6'h17: lut_cos=9'h111;
6'h18: lut_cos=9'h11C;
6'h19: lut_cos=9'h126;
6'h1a: lut_cos=9'h130;
6'h1b: lut_cos=9'h13A;
6'h1c: lut_cos=9'h144;
6'h1d: lut_cos=9'h14E;
6'h1e: lut_cos=9'h157;
6'h1f: lut_cos=9'h161;
6'h20: lut_cos=9'h16A;
6'h21: lut_cos=9'h172;
6'h22: lut_cos=9'h17B;
6'h23: lut_cos=9'h183;
6'h24: lut_cos=9'h18B;
6'h25: lut_cos=9'h193;
6'h26: lut_cos=9'h19B;
6'h27: lut_cos=9'h1A2;
6'h28: lut_cos=9'h1A9;
6'h29: lut_cos=9'h1B0;
6'h2a: lut_cos=9'h1B7;
6'h2b: lut_cos=9'h1BD;
6'h2c: lut_cos=9'h1C3;
6'h2d: lut_cos=9'h1C9;
6'h2e: lut_cos=9'h1CE;
6'h2f: lut_cos=9'h1D4;
6'h30: lut_cos=9'h1D9;
6'h31: lut_cos=9'h1DD;
6'h32: lut_cos=9'h1E2;
6'h33: lut_cos=9'h1E6;
6'h34: lut_cos=9'h1E9;
6'h35: lut_cos=9'h1ED;
6'h36: lut_cos=9'h1F0;
6'h37: lut_cos=9'h1F3;
6'h38: lut_cos=9'h1F6;
6'h39: lut_cos=9'h1F8;
6'h3a: lut_cos=9'h1FA;
6'h3b: lut_cos=9'h1FC;
6'h3c: lut_cos=9'h1FD;
6'h3d: lut_cos=9'h1FE;
6'h3e: lut_cos=9'h1FF;
6'h3f: lut_cos=9'h1FF;
endcase
end
endmodule
encoder:
module encoder(
input sys_clk,
input sys_rst_n,
input encoder_a,
input encoder_b,
input encoder_s,
output reg encoder_left,
output reg encoder_right,
output reg encoder_ok
);
parameter CNT_20MS_MAX = 240_000; //To scan keys
parameter CNT_1MS_MAX = 12_000; //To get 1k sample rate
//To D-reg the S input to sync data
reg r_encoder_s;
always@(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
r_encoder_s <= 1'b0;
end else begin
r_encoder_s <= encoder_s;
end
end
//To provide 20ms counter to filter keys
reg [19:0] cnt_20ms;
always@(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
cnt_20ms <= 20'd0;
end else if(encoder_s == 1'b0)begin
cnt_20ms <= 20'd0;
end else if(cnt_20ms == CNT_20MS_MAX - 1 && encoder_s == 1'b1)begin
cnt_20ms <= cnt_20ms;
end else begin
cnt_20ms <= cnt_20ms + 1'b1;
end
end
//To provide 1 clock cycle signal
always@(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
encoder_ok <= 1'b0;
end else if(cnt_20ms == CNT_20MS_MAX - 2)begin
encoder_ok <= 1'b1;
end else begin
encoder_ok <= 1'b0;
end
end
//The counter of 1k signal
reg [15:0] cnt_1ms;
always@(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
cnt_1ms <= 16'd0;
end else if(cnt_1ms == CNT_1MS_MAX - 1)begin
cnt_1ms <= 16'd0;
end else begin
cnt_1ms <= cnt_1ms + 1'b1;
end
end
//To D-reg the A&B input to sync data using 1k clock
reg r_encoder_a,rr_encoder_a;
reg r_encoder_b,rr_encoder_b;
always@(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
r_encoder_a <= 1'b0;
r_encoder_b <= 1'b0;
rr_encoder_a <= 1'b0;
rr_encoder_b <= 1'b0;
end else if(cnt_1ms == CNT_1MS_MAX - 1)begin
r_encoder_a <= encoder_a;
r_encoder_b <= encoder_b;
rr_encoder_a <= r_encoder_a;
rr_encoder_b <= r_encoder_b;
end
end
wire state_a = encoder_a && r_encoder_a && rr_encoder_a;
wire state_b = encoder_b && r_encoder_b && rr_encoder_b;
reg r_state_a;
always@(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
r_state_a <= 1'b0;
end else begin
r_state_a <= state_a;
end
end
//To get the rise_edge and fall_edge
wire encoder_a_rise;
wire encoder_a_fall;
assign encoder_a_rise = (r_state_a | state_a)&(r_state_a == 1'b0);
assign encoder_a_fall = (r_state_a | state_a)&(state_a == 1'b0);
always@(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
encoder_left <= 1'b0;
encoder_right <= 1'b0;
end else if((encoder_a_rise && rr_encoder_b)||(encoder_a_fall && !rr_encoder_b))begin
encoder_left <= 1'b1;
encoder_right <= 1'b0;
end else if((encoder_a_fall && rr_encoder_b)||(encoder_a_rise && !rr_encoder_b))begin
encoder_right <= 1'b1;
encoder_left <= 1'b0;
end else begin
encoder_left <= 1'b0;
encoder_right <= 1'b0;
end
end
endmodule
此项目所占用FPGA内部资源报告:
Design Information
Command line: map -a MachXO2 -p LCMXO2-4000HC -t CSBGA132 -s 4 -oc Commercial
dds_freq_meter_impl1.ngd -o dds_freq_meter_impl1_map.ncd -pr
dds_freq_meter_impl1.prf -mp dds_freq_meter_impl1.mrp -lpf C:/Users/10943/D
esktop/DDS/XO2-4000HC/project/impl1/dds_freq_meter_impl1_synplify.lpf -lpf
C:/Users/10943/Desktop/DDS/XO2-4000HC/project/dds_freq_meter.lpf -c 0 -gui
Target Vendor: LATTICE
Target Device: LCMXO2-4000HCCSBGA132
Target Performance: 4
Mapper: xo2c00, version: Diamond (64-bit) 3.12.0.240.2
Mapped on: 02/25/22 20:31:14
Design Summary
Number of registers: 355 out of 4635 (8%)
PFU registers: 349 out of 4320 (8%)
PIO registers: 6 out of 315 (2%)
Number of SLICEs: 761 out of 2160 (35%)
SLICEs as Logic/ROM: 761 out of 2160 (35%)
SLICEs as RAM: 0 out of 1620 (0%)
SLICEs as Carry: 154 out of 2160 (7%)
Number of LUT4s: 1515 out of 4320 (35%)
Number used as logic LUTs: 1207
Number used as distributed RAM: 0
Number used as ripple logic: 308
Number used as shift registers: 0
Number of PIO sites used: 20 + 4(JTAG) out of 105 (23%)
Number of block RAMs: 0 out of 10 (0%)
Number of GSRs: 1 out of 1 (100%)
EFB used : No
JTAG used : No
Readback used : No
Oscillator used : No
Startup used : No
POR : On
Bandgap : On
Number of Power Controller: 0 out of 1 (0%)
Number of Dynamic Bank Controller (BCINRD): 0 out of 6 (0%)
Number of Dynamic Bank Controller (BCLVDSO): 0 out of 1 (0%)
Number of DCCA: 0 out of 8 (0%)
Number of DCMA: 0 out of 2 (0%)
Number of PLLs: 1 out of 2 (50%)
Number of DQSDLLs: 0 out of 2 (0%)
Number of CLKDIVC: 0 out of 4 (0%)
Number of ECLKSYNCA: 0 out of 4 (0%)
Number of ECLKBRIDGECS: 0 out of 2 (0%)
Notes:-
1. Total number of LUT4s = (Number of logic LUT4s) + 2*(Number of
distributed RAMs) + 2*(Number of ripple logic)
2. Number of logic LUT4s does not include count of distributed RAM and
ripple logic.
Number of clocks: 3
Net in_clk_c: 1 loads, 1 rising, 0 falling (Driver: PIO in_clk )
Net sys_clk: 170 loads, 170 rising, 0 falling (Driver: u_pll/PLLInst_0 )
Net dac_clk_c: 31 loads, 31 rising, 0 falling (Driver: u_pll/PLLInst_0 )
Number of Clock Enables: 19
Net u_oled12864.un1_state_22_i: 1 loads, 0 LSLICEs
Net u_encoder.cnt_1ms8: 3 loads, 1 LSLICEs
Net u_oled12864.N_827_i: 1 loads, 0 LSLICEs
Net u_oled12864/N_820_i: 1 loads, 1 LSLICEs
Net u_oled12864/u_bcd_8421/unit5: 8 loads, 8 LSLICEs
Net u_oled12864/u_bcd_8421/M_0_sqmuxa: 4 loads, 4 LSLICEs
Net u_oled12864/u_bcd_8421/un4_i: 27 loads, 27 LSLICEs
Net u_oled12864/state[6]: 3 loads, 3 LSLICEs
Net u_oled12864/N_906_i: 3 loads, 3 LSLICEs
Net u_oled12864.un1_state_54_i: 5 loads, 4 LSLICEs
Net u_oled12864/un1_state_62_i: 2 loads, 2 LSLICEs
Net u_oled12864/N_355: 31 loads, 31 LSLICEs
Net u_oled12864/nume: 4 loads, 4 LSLICEs
Net u_oled12864/N_872_i: 3 loads, 3 LSLICEs
Net u_oled12864/N_229_i: 3 loads, 3 LSLICEs
Net u_oled12864/N_230_i: 2 loads, 2 LSLICEs
Net u_oled12864/cnt_delaye: 8 loads, 8 LSLICEs
Net un1_state_53_0: 1 loads, 0 LSLICEs
Net u_encoder/cnt_20mse: 11 loads, 11 LSLICEs
Number of LSRs: 3
Net encoder_a_c: 1 loads, 1 LSLICEs
Net type_ctrl[0]: 1 loads, 1 LSLICEs
Net u_encoder/cnt_20ms[16]: 1 loads, 1 LSLICEs
Number of nets driven by tri-state buffers: 0
Top 10 highest fanout non-clock nets:
Net u_oled12864/N_1_i: 214 loads
Net u_oled12864/N_4_i: 201 loads
Net u_oled12864/N_476: 185 loads
Net u_oled12864/N_1_i_0: 159 loads
Net u_oled12864/N_477: 138 loads
Net u_oled12864/num[4]: 73 loads
Net u_oled12864/N_478: 67 loads
Net u_oled12864/state[0]: 62 loads
Net u_oled12864/state[1]: 57 loads
Net u_oled12864/u_bcd_8421/shift_flag: 56 loads
Number of warnings: 0
Number of errors: 0
遇到的主要难题及解决方法:
由于是第一次接触FPGA,花了一些时间去学习Verilog HDL语言,去学习相关开发软件diamond的使用,学习FPGA的主要开发流程。深深体会到了FPGA的强大,逻辑上的错误可能导致非常严重的结果。
未来的计划或建议:
继续更加深入地学习了解FPGA领域、嵌入式领域相关的知识,可以独立的完成更多有趣、有意义的项目。