hzr0071 发表于 2011-5-5 18:30:31

cpld有这么费单元吗?

刚刚学cpld不长时间。写了一个简单的两位数码管动态驱动+十进制计时就用掉的97%(232/240)的单元(我用的是epm240)。那想再多写点不就完了吗。
这cpld单元有这么不够用么。。。。

flyforyou85 发表于 2011-5-5 18:35:16

你的程序肯定有问题了,如何效率这么低,CPLD早就没生路了。
一个EMP240可以完成SRAM的控制,加上VGA图像控制器,以及MCU接口定义。

hzr0071 发表于 2011-5-5 18:57:18

我把代码贴上来,师傅们帮我看看这代码应该替换哪里才能让程序变得小巧。
分频器占了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

1ongquan 发表于 2011-5-5 20:00:47

用电路图7449搭了一个,资源消耗很少

hzr0071 发表于 2011-5-5 21:51:39

把除法器和余数器一去,我勒个去,去掉了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

dr2001 发表于 2011-5-5 22:08:31

认真拜读所用的CPLD的手册,了解一下内部逻辑结构,就能知道为啥CPLD逻辑那么“费”宏单元了。

hzr0071 发表于 2011-5-5 22:14:38

回复【5楼】dr2001
-----------------------------------------------------------------------

MAX II 用户手册。。。。英文的。。。俺看不懂。。。俺连六级都没过。。。。。哭。。。。。。

dr2001 发表于 2011-5-5 22:26:39

学就一个字。

技术手册还是要看原版的,翻译一点小歧义可能搞死个人。
页: [1]
查看完整版本: cpld有这么费单元吗?