cpld有这么费单元吗?
刚刚学cpld不长时间。写了一个简单的两位数码管动态驱动+十进制计时就用掉的97%(232/240)的单元(我用的是epm240)。那想再多写点不就完了吗。这cpld单元有这么不够用么。。。。 你的程序肯定有问题了,如何效率这么低,CPLD早就没生路了。
一个EMP240可以完成SRAM的控制,加上VGA图像控制器,以及MCU接口定义。 我把代码贴上来,师傅们帮我看看这代码应该替换哪里才能让程序变得小巧。
分频器占了18%,两位数码管驱动占了66%,这数据量吓死我了。。。。
两位数码管驱动单元
module seg7dirver(
clk,rst_n,
sm_cs1_n,sm_cs2_n,sm_db,
sm_data
);
input clk;
input rst_n;
input sm_data;
output sm_cs1_n,sm_cs2_n;
output sm_db;
reg wei1,wei2;
reg sm_data_r;
always @ (posedge clk or negedge rst_n)
if(!rst_n)
begin
sm_data_r<=0;
wei1<=0;
wei2<=0;
end
else
begin
if(sm_data_r!=sm_data)
begin
sm_data_r<=sm_data;
wei1<=sm_data%10;
wei2<=sm_data/10;
end
end
reg sm1_dbr,sm2_dbr;
always @ (posedge clk or negedge rst_n)
if(!rst_n)
beginsm1_dbr<=0;
sm2_dbr<=0;
end
else
beginsm1_dbr<=Receive(wei1);
sm2_dbr<=Receive(wei2);
end
reg sm_cs1_nr,sm_cs2_nr;
assign sm_cs1_n = sm_cs1_nr;
assign sm_cs2_n = sm_cs2_nr;
reg sm_dbr;
assign sm_db = sm_dbr;
reg cntds;
always @(posedge clk or negedge rst_n)
if(!rst_n)cntds<=0;
else
begin
cntds<=cntds+1;
if(cntds==11)cntds<=0;
end
always @ (posedge clk or negedge rst_n)
if(!rst_n)sm_dbr<=0;
else
begin
case(cntds)
7'd0:
begin
sm_cs1_nr<=1;
sm_cs2_nr<=1;
end
7'd1:
begin
sm_cs1_nr<=0;
sm_dbr<=sm1_dbr;
end
7'd5:begin
sm_cs1_nr<=1;
sm_cs2_nr<=1;
end
7'd6:begin
sm_cs2_nr<=0;
sm_dbr<=sm2_dbr;
end
default:;
endcase
end
parameter seg0 = 7'h3f,
seg1 = 7'h06,
seg2 = 7'h5b,
seg3 = 7'h4f,
seg4 = 7'h66,
seg5 = 7'h6d,
seg6 = 7'h7d,
seg7 = 7'h07,
seg8 = 7'h7f,
seg9 = 7'h6f,
sega = 7'h77,
segb = 7'h7c,
segc = 7'h39,
segd = 7'h5e,
sege = 7'h79,
segf = 7'h71;
function Receive;
input Byte;
begin
case (Byte)
4'h0: Receive = seg0;
4'h1: Receive = seg1;
4'h2: Receive = seg2;
4'h3: Receive = seg3;
4'h4: Receive = seg4;
4'h5: Receive = seg5;
4'h6: Receive = seg6;
4'h7: Receive = seg7;
4'h8: Receive = seg8;
4'h9: Receive = seg9;
4'ha: Receive = sega;
4'hb: Receive = segb;
4'hc: Receive = segc;
4'hd: Receive = segd;
4'he: Receive = sege;
4'hf: Receive = segf;
default: ;
endcase
end
endfunction
endmodule
分频器单元
module cntnum(clk,rst_n,num);
input clk,rst_n;
output num;
reg cnt; //¼ÆÊýÆ÷£¬×î´ó¿ÉÒÔ¼ÆÊýµ½2µÄ25´Î·½*20ns=640ms
always @ (posedge clk or negedge rst_n)
if(!rst_n) cnt <= 25'd0;
else cnt <= cnt+1'b1; //Ñ»·¼ÆÊý
reg num_r;
always@(posedge clk or negedge rst_n)
if(!rst_n)num_r<=0;
else
begin
if(cnt == 25'h1ffffff)
begin
num_r<=num_r+1;
if(num_r>19)num_r<=0;
end
end
assign num=num_r;
endmodule 用电路图7449搭了一个,资源消耗很少 把除法器和余数器一去,我勒个去,去掉了50%的单元。这样就是显示16进制的数。
然后有优化了一下,把状态机精简一下(只适合两位数码管),然后把查表写成一个模块,然后调用(我知道不应该在模块中使用模块,不过这样的确好用,以前写C写习惯了)。
问题基本上解决,现在只占用了30%的单元(数码管驱动只用了总量的12%,NND,那计时器用了18%),附上代码。
module seg7dirver(
clk,rst_n,
sm_cs1_n,sm_cs2_n,sm_db,
sm_data
);
input clk;
input rst_n;
input sm_data;
output sm_cs1_n,sm_cs2_n;
output sm_db;
reg wei1,wei2;
reg sm_data_r;
always @ (posedge clk or negedge rst_n)
if(!rst_n)
begin
sm_data_r<=0;
wei1<=0;
wei2<=0;
end
else
begin
if(sm_data_r!=sm_data)
begin
sm_data_r<=sm_data;
wei1<=sm_data;
wei2<=sm_data>>4;
end
end
reg sm_cs1_nr,sm_cs2_nr;
assign sm_cs1_n = sm_cs1_nr;
assign sm_cs2_n = sm_cs2_nr;
reg cntds;
always @(posedge clk or negedge rst_n)
if(!rst_n)cntds<=0;
else
begin
cntds<=cntds+1;
if(cntds>9)cntds<=0;
end
always @ (posedge clk or negedge rst_n)
if(!rst_n)
begin
weitemp<=0;
sm_cs1_nr<=1;
sm_cs2_nr<=1;
clk_r<=1;
end
else
begin
case(cntds)
4'd0,4'd5:
begin
sm_cs1_nr<=1;
sm_cs2_nr<=1;
clk_r<=1;
end
4'd1:
begin
weitemp<=wei1;
clk_r<=0;
sm_cs1_nr<=0;
end
4'd6:begin
weitemp<=wei2;
clk_r<=0;
sm_cs2_nr<=0;
end
default:clk_r<=1;
endcase
end
regweitemp;
reg clk_r;
tst trans(.wei(weitemp),
.sm_db(sm_db),
.clk(clk_r),
.rst_n(rst_r));
endmodule
/*****************************查表模块*********************************************************/
module tst(wei,sm_db,clk,rst_n);
input wei,clk,rst_n;
output sm_db;
reg weidata;
reg sm_dbr;
always @(posedge clk or negedge rst_n)
begin
weidata<=wei;
case (weidata)
4'h0: sm_dbr <= seg0;
4'h1: sm_dbr <= seg1;
4'h2: sm_dbr <= seg2;
4'h3: sm_dbr <= seg3;
4'h4: sm_dbr <= seg4;
4'h5: sm_dbr <= seg5;
4'h6: sm_dbr <= seg6;
4'h7: sm_dbr <= seg7;
4'h8: sm_dbr <= seg8;
4'h9: sm_dbr <= seg9;
4'ha: sm_dbr <= sega;
4'hb: sm_dbr <= segb;
4'hc: sm_dbr <= segc;
4'hd: sm_dbr <= segd;
4'he: sm_dbr <= sege;
4'hf: sm_dbr <= segf;
default: ;
endcase
end
parameter seg0 = 7'h3f,
seg1 = 7'h06,
seg2 = 7'h5b,
seg3 = 7'h4f,
seg4 = 7'h66,
seg5 = 7'h6d,
seg6 = 7'h7d,
seg7 = 7'h07,
seg8 = 7'h7f,
seg9 = 7'h6f,
sega = 7'h77,
segb = 7'h7c,
segc = 7'h39,
segd = 7'h5e,
sege = 7'h79,
segf = 7'h71;
assign sm_db=sm_dbr;
endmodule 认真拜读所用的CPLD的手册,了解一下内部逻辑结构,就能知道为啥CPLD逻辑那么“费”宏单元了。 回复【5楼】dr2001
-----------------------------------------------------------------------
MAX II 用户手册。。。。英文的。。。俺看不懂。。。俺连六级都没过。。。。。哭。。。。。。 学就一个字。
技术手册还是要看原版的,翻译一点小歧义可能搞死个人。
页:
[1]