今天是世界末日,我在拯救了地球之后抽了点时间玩板子。
连着几天弄12864失败,对俺的信心打击很大。决定搞点简单的实验找找信心。
参考anmko进程贴,试玩PLL。
实验过程是这样的:
将ALT的PLL加入到工程,分别产生三个频率输出: c0 50M,c1 100M ,c2 150M。
对输出的频率分别计数25000000次,计满之后控制3个LED反转。同时将晶振输入进行25000000计数并控制LED反转。
观察实验现象,可看见是个led的频率差异。c1、c2控制的led闪烁明显要快些.
实验中同时使用了Y1晶振来作为PLL2的输入激励。可是我没焊接Y1晶振。于是PLL2输出所控制的LED保持常亮。
代码参考anmko进程贴:http://forum.eepw.com.cn/thread/221172/16#158
视频正在上传
32楼
在折腾了几天驱动并失败之后,我觉得还是从基础实验做起吧。写点简单的程序,练习Verilog。
因为写驱动实在是太麻烦了,有时候一整天一行代码都写不出。根本谈不上练习Verilog了
于是今天晚上就做了几个。
第一个是简单的计数器,
/*************************************************
* Module Name : 计数器
* Engineer : hanshuyujifen
* Target Device : EP2C5Q208C8
* Tool versions :
* Create Date :
* Revision : v1.0
* Description :
**************************************************/
module COUNTER_EN(en,clk,rst,out);
parameter Width = 8; //参数,位宽
parameter U_DLY = 1;
input en,clk,rst;
output [Width-1:0] out;
reg [Width-1:0] out;
always @(posedge clk or negedge rst)
begin
if(!rst)
out <= 8'b0;
else
out<= #U_DLY out +1'b1; //这里的#U_DLY 不知道是什么意思
end
endmodule
第二个实验是练习加减乘除运算符的使用:
/*************************************************
* Module Name : 算数操作
* Engineer : hanshuyujifen
* Target Device : EP2C5Q208C8
* Tool versions : QII12
* Create Date : 2012-12-23
* Revision : v1.0
* Description : 加减乘除运算
**************************************************/
module ARTITHMETIC(A,B,Q1,Q2,Q3,Q4);
input [3:0] A,B; //输入
output [4:0] Q1; //加法输出
output [3:0] Q2; //减法输出
output [3:0] Q3; //除法
output [7:0] Q4; //乘法
reg [4:0] Q1;
reg [3:0] Q2;
reg [3:0] Q3;
reg [7:0] Q4;
always @(A or B)
begin
Q1 = A+B;
Q2 = A-B;
Q3 = A/2;
Q4 = A*B;
end
endmodule
最后一个,关系运算符练习:
module relational(A,B,Q1,Q2,Q3,Q4);
input [3:0] A,B;
output Q1,Q2,Q3,Q4;
reg Q1,Q2,Q3,Q4;
//电平触发
always@(A or B)
begin
Q1 = A>B;
Q2 = A<B;
Q3 = A>=B;
if(A<=B)
Q4 = 1;
else
Q4 = 0;
end
endmodule
这些模块都单独放置在一个文件里边,另建一个文件top.v,使用信号映射法调用这些模块:
module top(A,B,Q1,Q2,Q3,Q4);
input [3:0] A,B;
output Q1,Q2,Q3,Q4;
relational r1(
.A(A),
.B(B),
.Q1(Q1),
.Q2(Q2),
.Q3(Q3),
.Q4(Q4)
);
endmodule
因为写驱动实在是太麻烦了,有时候一整天一行代码都写不出。根本谈不上练习Verilog了
于是今天晚上就做了几个。
第一个是简单的计数器,
/*************************************************
* Module Name : 计数器
* Engineer : hanshuyujifen
* Target Device : EP2C5Q208C8
* Tool versions :
* Create Date :
* Revision : v1.0
* Description :
**************************************************/
module COUNTER_EN(en,clk,rst,out);
parameter Width = 8; //参数,位宽
parameter U_DLY = 1;
input en,clk,rst;
output [Width-1:0] out;
reg [Width-1:0] out;
always @(posedge clk or negedge rst)
begin
if(!rst)
out <= 8'b0;
else
out<= #U_DLY out +1'b1; //这里的#U_DLY 不知道是什么意思
end
endmodule
第二个实验是练习加减乘除运算符的使用:
/*************************************************
* Module Name : 算数操作
* Engineer : hanshuyujifen
* Target Device : EP2C5Q208C8
* Tool versions : QII12
* Create Date : 2012-12-23
* Revision : v1.0
* Description : 加减乘除运算
**************************************************/
module ARTITHMETIC(A,B,Q1,Q2,Q3,Q4);
input [3:0] A,B; //输入
output [4:0] Q1; //加法输出
output [3:0] Q2; //减法输出
output [3:0] Q3; //除法
output [7:0] Q4; //乘法
reg [4:0] Q1;
reg [3:0] Q2;
reg [3:0] Q3;
reg [7:0] Q4;
always @(A or B)
begin
Q1 = A+B;
Q2 = A-B;
Q3 = A/2;
Q4 = A*B;
end
endmodule
最后一个,关系运算符练习:
module relational(A,B,Q1,Q2,Q3,Q4);
input [3:0] A,B;
output Q1,Q2,Q3,Q4;
reg Q1,Q2,Q3,Q4;
//电平触发
always@(A or B)
begin
Q1 = A>B;
Q2 = A<B;
Q3 = A>=B;
if(A<=B)
Q4 = 1;
else
Q4 = 0;
end
endmodule
这些模块都单独放置在一个文件里边,另建一个文件top.v,使用信号映射法调用这些模块:
module top(A,B,Q1,Q2,Q3,Q4);
input [3:0] A,B;
output Q1,Q2,Q3,Q4;
relational r1(
.A(A),
.B(B),
.Q1(Q1),
.Q2(Q2),
.Q3(Q3),
.Q4(Q4)
);
endmodule
33楼
移位运算符>>和<<使用
module shifter(Data,Q1,Q2);
input [3:0] Data;
output [3:0] Q1,Q2;
parameter B = 2;
reg [3:0] Q1,Q2;
always @(Data)
begin
Q1 = Data<<B;
Q2 = Data>>B;
end
endmodule
试验了移位操作。
以下是参数化调用这个方法,因为模块里边有个参数B。
一种是使用#,一种是使用关键字defparam.路径的方法
module top(Data1,Data2,Q1,Q2,Q3,Q4);
input [3:0] Data1,Data2;
output Q1,Q2,Q3,Q4;
wire [3:0] Data;
reg [3:0] databuf1,databuf2;
//参数传递的方法1
shifter#(5) S1(
.Data(Data1),
.Q1(Q1),
.Q2(Q2)
);
//参数传递方法2
shifter S2(
.Data(Data2),
.Q1(Q3),
.Q2(Q4)
);
defparam S2.B = 3;
endmodule
module shifter(Data,Q1,Q2);
input [3:0] Data;
output [3:0] Q1,Q2;
parameter B = 2;
reg [3:0] Q1,Q2;
always @(Data)
begin
Q1 = Data<<B;
Q2 = Data>>B;
end
endmodule
试验了移位操作。
以下是参数化调用这个方法,因为模块里边有个参数B。
一种是使用#,一种是使用关键字defparam.路径的方法
module top(Data1,Data2,Q1,Q2,Q3,Q4);
input [3:0] Data1,Data2;
output Q1,Q2,Q3,Q4;
wire [3:0] Data;
reg [3:0] databuf1,databuf2;
//参数传递的方法1
shifter#(5) S1(
.Data(Data1),
.Q1(Q1),
.Q2(Q2)
);
//参数传递方法2
shifter S2(
.Data(Data2),
.Q1(Q3),
.Q2(Q4)
);
defparam S2.B = 3;
endmodule
34楼
体会下什么叫同步什么叫异步。感觉同步就应该是信号来了马上变化,异步就是信号来了等到下一个时钟才变化。
同步复位器是这样的:
module dff_sync_rst(clk,rst,data,q);
input clk,rst,data;
output q;
parameter U_DLY = 1;
reg q;
always @(posedge clk)
begin
if(!rst)
q<= #U_DLY 1'b0;
else
q<= #U_DLY data;
end
endmodule
顶层模块调用:
module top(clk,rst,data,q);
input clk,rst,data;
output q;
dff_sync_rst dff1(
.clk(clk),
.rst(rst),
.data(data),
.q(q)
);
defparam dff1.U_DLY = 2;
endmodule
这个U_DLY不知道神干什么的,应该是仿真时候用的吧?因为RTL View里边没没看见什么效果。求解
同步复位器是这样的:
module dff_sync_rst(clk,rst,data,q);
input clk,rst,data;
output q;
parameter U_DLY = 1;
reg q;
always @(posedge clk)
begin
if(!rst)
q<= #U_DLY 1'b0;
else
q<= #U_DLY data;
end
endmodule
顶层模块调用:
module top(clk,rst,data,q);
input clk,rst,data;
output q;
dff_sync_rst dff1(
.clk(clk),
.rst(rst),
.data(data),
.q(q)
);
defparam dff1.U_DLY = 2;
endmodule
这个U_DLY不知道神干什么的,应该是仿真时候用的吧?因为RTL View里边没没看见什么效果。求解
35楼
使能信号en控制输出
module dff_ck_en(clk,rst,en,data,q);
input clk,rst,en,data;
output q;
parameter U_DLY = 1;
reg q;
always @(posedge clk or negedge rst)
begin
if(!rst)
q <= 1'b0;
else if(en)
q <= #U_DLY data;
else
q<= #U_DLY 1;
end
endmodule
顶层调用,信号映射法:
module top(clk,rst,en,data,q);
input clk,rst,en,data;
output q;
dff_ck_en dce(
.clk(clk),
.rst(rst),
.en(en),
.data(data),
.q(q)
);
endmodule
module dff_ck_en(clk,rst,en,data,q);
input clk,rst,en,data;
output q;
parameter U_DLY = 1;
reg q;
always @(posedge clk or negedge rst)
begin
if(!rst)
q <= 1'b0;
else if(en)
q <= #U_DLY data;
else
q<= #U_DLY 1;
end
endmodule
顶层调用,信号映射法:
module top(clk,rst,en,data,q);
input clk,rst,en,data;
output q;
dff_ck_en dce(
.clk(clk),
.rst(rst),
.en(en),
.data(data),
.q(q)
);
endmodule
36楼
vga显示使用了模块化设计,将整个模块分为VGA控制模块和视频同步模块。
下边是VGA同步模块及注释
根据anmko进程贴里边的说明,50MHZ晶振选择使用860×600×60HZ显示效果最好。
这个模块控制产生VGA显示所需的行同步和场同步信号。
同时产生当前行是否在有效显示区域信号、当前显示的行地址和列地址。
VGA显示时序分析可参考anmko进程贴,贴图太麻烦了。俺懒
/*************************************************
* Module Name : sync_module
* Engineer : hanshuyujifen
* Target Device : EP2C5Q208C8
* Tool versions :
* Create Date :
* Revision : v1.0
* Description : VGA显示同步控制模块
**************************************************/
//sys_clk 50MHZ时钟
module sync_module(sys_clk,sys_rstn,vga_hsync,vga_vsync,isReady,Colum_add_sig,Row_add_sig);
input sys_clk,sys_rstn;
output vga_hsync,vga_vsync,isReady;
output [10:0] Colum_add_sig;
output [9:0] Row_add_sig;
reg [10:0] h_cnt;
reg [9:0] v_cnt;
reg isReady;
//产生vga_hsync信号
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
h_cnt <= 11'd0;
else
begin
if(h_cnt == 11'd1039)
h_cnt<=11'd0;
else
h_cnt<=h_cnt+1'b1;
end
end
assign vga_hsync = ~((h_cnt>=0)&&(h_cnt<120)); //产生行同步信号
//产生vga_vsync信号
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
v_cnt <= 10'd0;
else
begin
if(v_cnt == 10'd665)
v_cnt <= 10'd0;
else if(h_cnt == 11'd1039)
v_cnt <= v_cnt+1'b1;
else
v_cnt <= v_cnt;
end
end
assign vga_vsync = (v_cnt>=0)&&(v_cnt<6); //场同步信号
//输出是否在有效区域
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
isReady <= 1'b0;
else
isReady <= (h_cnt>=180 && h_cnt<986) &&(v_cnt>= 27 && v_cnt< 631);
end
//输出当前地址(x,y)
assign Colum_add_sig = isReady ? h_cnt-11'd181 : 11'd0;
assign Row_add_sig = isReady ?v_cnt - 10'd27 : 10'd0;
endmodule
38楼
显示VGA黑白条。。。只是黑白,彩色的还没做
显示图形也没做
/*************************************************
* Module Name : vga_control_module
* Engineer : hanshuyujifen
* Target Device : EP2C5Q208C8
* Tool versions :
* Create Date :
* Revision : v1.0
* Description :
**************************************************/
module vga_control_module(sys_clk,sys_rstn,ready_sig,
colum_add,row_add,
vga_r2,vga_r1,vga_r0,
vga_g2,vga_g1,vga_g0,
vga_b1,vga_b0);
input sys_clk,sys_rstn;
input ready_sig;
input [10:0] colum_add;
input [9:0] row_add;
output vga_r2,vga_r1,vga_r0;
output vga_g2,vga_g1,vga_g0;
output vga_b1,vga_b0;
reg isRectangle;
always@(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
isRectangle <= 1'b0;
else if(colum_add>11'd0 && row_add < 10'd100)
isRectangle <= 1'b1;
else if(colum_add>11'd0 && row_add > 10'd200 && row_add < 10'd300)
isRectangle <= 1'b1;
else if(colum_add>11'd0 && row_add > 10'd400 && row_add < 10'd500)
isRectangle <= 1'b1;
else if(colum_add>11'd0 && row_add > 10'd600 && row_add < 10'd640)
isRectangle <= 1'b1;
else
isRectangle <= 1'b0;
end
assign vga_r2 = ready_sig && isRectangle ? 1'b1 : 1'b0;
assign vga_r1 = ready_sig && isRectangle ? 1'b1 : 1'b0;
assign vga_r0 = ready_sig && isRectangle ? 1'b1 : 1'b0;
assign vga_g2 = ready_sig && isRectangle ? 1'b1 : 1'b0;
assign vga_g1 = ready_sig && isRectangle ? 1'b1 : 1'b0;
assign vga_g0 = ready_sig && isRectangle ? 1'b1 : 1'b0;
assign vga_b1 = ready_sig && isRectangle ? 1'b1 : 1'b0;
assign vga_b0 = ready_sig && isRectangle ? 1'b1 : 1'b0;
endmodule
显示图形也没做
/*************************************************
* Module Name : vga_control_module
* Engineer : hanshuyujifen
* Target Device : EP2C5Q208C8
* Tool versions :
* Create Date :
* Revision : v1.0
* Description :
**************************************************/
module vga_control_module(sys_clk,sys_rstn,ready_sig,
colum_add,row_add,
vga_r2,vga_r1,vga_r0,
vga_g2,vga_g1,vga_g0,
vga_b1,vga_b0);
input sys_clk,sys_rstn;
input ready_sig;
input [10:0] colum_add;
input [9:0] row_add;
output vga_r2,vga_r1,vga_r0;
output vga_g2,vga_g1,vga_g0;
output vga_b1,vga_b0;
reg isRectangle;
always@(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
isRectangle <= 1'b0;
else if(colum_add>11'd0 && row_add < 10'd100)
isRectangle <= 1'b1;
else if(colum_add>11'd0 && row_add > 10'd200 && row_add < 10'd300)
isRectangle <= 1'b1;
else if(colum_add>11'd0 && row_add > 10'd400 && row_add < 10'd500)
isRectangle <= 1'b1;
else if(colum_add>11'd0 && row_add > 10'd600 && row_add < 10'd640)
isRectangle <= 1'b1;
else
isRectangle <= 1'b0;
end
assign vga_r2 = ready_sig && isRectangle ? 1'b1 : 1'b0;
assign vga_r1 = ready_sig && isRectangle ? 1'b1 : 1'b0;
assign vga_r0 = ready_sig && isRectangle ? 1'b1 : 1'b0;
assign vga_g2 = ready_sig && isRectangle ? 1'b1 : 1'b0;
assign vga_g1 = ready_sig && isRectangle ? 1'b1 : 1'b0;
assign vga_g0 = ready_sig && isRectangle ? 1'b1 : 1'b0;
assign vga_b1 = ready_sig && isRectangle ? 1'b1 : 1'b0;
assign vga_b0 = ready_sig && isRectangle ? 1'b1 : 1'b0;
endmodule
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
vscode+cmake搭建雅特力AT32L021开发环境被打赏30分 | |
【换取逻辑分析仪】自制底板并驱动ArduinoNanoRP2040ConnectLCD扩展板被打赏47分 | |
【分享评测,赢取加热台】RISC-V GCC 内嵌汇编使用被打赏38分 | |
【换取逻辑分析仪】-基于ADI单片机MAX78000的简易MP3音乐播放器被打赏48分 | |
我想要一部加热台+树莓派PICO驱动AHT10被打赏38分 | |
【换取逻辑分析仪】-硬件SPI驱动OLED屏幕被打赏36分 | |
换逻辑分析仪+上下拉与多路选择器被打赏29分 | |
Let'sdo第3期任务合集被打赏50分 | |
换逻辑分析仪+Verilog三态门被打赏27分 | |
换逻辑分析仪+Verilog多输出门被打赏24分 |