原创 FPGA代码风格(一):组合逻辑电路和时序逻辑电路分开编码

2010-2-8 12:54 4924 11 12 分类: FPGA/CPLD

              这是地球人都知道的编码风格,但是在阅读别人的代码的时候,还是经常看到组合逻辑和时序逻辑混在一起。怎样才能很好地将组合逻辑电路和时序逻辑电路分开编码呢?我觉得应该对常见的组合电路和时序电路的编码非常熟悉,在设计中才能将代码和电路结合起来,才能很好地区分哪些是组合逻辑,哪些是时序逻辑。下面举一个例子说明:


源代码1:


module code_style(clk,rst_n,data_out);
  
 input        clk     ;
 input        rst_n   ;
 output       data_out;
 
 reg  [2:0]   cnt     ;
 reg  [7:0]   data_out;
 
 always @ (posedge clk or negedge rst_n)
   begin
      if(rst_n == 1'b0)
      begin
       cnt      <= 3'b0;
     data_out <= 8'b0;
    end
    else
      begin
       cnt <= cnt + 1'b1;
     case(cnt)
        3'b000  : data_out <= 8'b0000_0001;
        3'b001  : data_out <= 8'b0000_0010;
        3'b010  : data_out <= 8'b0000_0100;
        3'b011  : data_out <= 8'b0000_1000;
        3'b100  : data_out <= 8'b0001_0000;
        3'b101  : data_out <= 8'b0010_0000;
        3'b110  : data_out <= 8'b0100_0010;
        3'b111  : data_out <= 8'b1000_0000;
        default  : data_out <= 8'b0000_0000;
     endcase
    end
   end


endmodule


读上面的程序,我们知道,是把计数值进行译码,很多人都知道,计数器是时序逻辑,译码是组合逻辑,于是可以将程序改写成:


源代码2:


module code_style(clk,rst_n,data_out);
  
 input          clk           ;
 input         rst_n        ;
 output       data_out  ;
 
 reg  [2:0]   cnt     ;
 reg  [7:0]   data_out;
 
 always @ (posedge clk or negedge rst_n)
   begin
      if(rst_n == 1'b0)  cnt <= 3'b0;
    else                         cnt <= cnt + 1'b1;
   end
  
 always @ (cnt)
   begin
   case(cnt)
        3'b000  : data_out = 8'b0000_0001;
        3'b001  : data_out = 8'b0000_0010;
        3'b010  : data_out = 8'b0000_0100;
        3'b011  : data_out = 8'b0000_1000;
        3'b100  : data_out = 8'b0001_0000;
        3'b101  : data_out = 8'b0010_0000;
        3'b110  : data_out = 8'b0100_0010;
        3'b111  : data_out = 8'b1000_0000;
        default  : data_out = 8'b0000_0000;
    endcase
 end
 
endmodule


源代码2这样书写将组合逻辑和时序逻辑分开写了,但是需要说明的是,这样改写是错误的,我们仿真就可以看出其中的玄机,


  源代码一仿真结果:



源代码二仿真结果:


 


为什么会这样呢?实际上源代码一中包含了两个时序逻辑,在译码完后,需要将译码结果寄存,然后再输出,而源代码二中并未寄存,但是源代码一中又不能很好地观察出来,所以真正的将组合逻辑和时序逻辑分开,而且时序也正确应该是下面的格式:


module code_style(clk,rst_n,data_out);
  
 input           clk       ;
 input          rst_n     ;
 output       data_out;
 
 reg  [2:0]   cnt                 ;
 reg  [7:0]   data_out_reg ;
 reg  [7:0]   data_out        ;
 
 always @ (posedge clk or negedge rst_n)
   begin
      if(rst_n == 1'b0)  cnt <= 3'b0;
     else                        cnt <= cnt + 1'b1;
   end
  
 always @ (cnt)
   begin
   case(cnt)
        3'b000  : data_out_reg = 8'b0000_0001;
        3'b001  : data_out_reg = 8'b0000_0010;
        3'b010  : data_out_reg = 8'b0000_0100;
        3'b011  : data_out_reg = 8'b0000_1000;
        3'b100  : data_out_reg = 8'b0001_0000;
        3'b101  : data_out_reg = 8'b0010_0000;
        3'b110  : data_out_reg = 8'b0100_0010;
        3'b111  : data_out_reg = 8'b1000_0000;
        default  : data_out_reg = 8'b0000_0000;
    endcase
     end
 
   always @ (posedge clk or negedge rst_n)
   begin
      if(rst_n == 1'b0) data_out <= 8'b0;
    else                       data_out <= data_out_reg;
   end
 
endmodule


这样组合逻辑和时序逻辑的层次就非常清楚了

文章评论1条评论)

登录后参与讨论

用户1562225 2012-4-14 17:33

我看不到图片 我把你的代码仿真 怎么出来是一样的呢
相关推荐阅读
用户244280 2011-04-09 02:19
有源晶振的EMC设计
    有源晶振的电路设计常见有两种:(1)、 (2)、原理图设计要点:(1)、晶振电源去耦非常重要,建议加磁珠,去耦电容选三个,容值递减。(2)、时钟输出管脚加匹配,具体匹配阻值,可根据测试结果而定...
用户244280 2011-04-05 12:46
三极管开关电路之一(基本电路)
       在板卡设计中,三极管开关电路用得非常多,然而却经常被人忽视。一位同事曾经对我说,都什么时代了,还用三极管。但是用得好的话,绝对事半功倍。        在最近的一次板卡上机调试中,由于板...
用户244280 2010-07-17 00:12
远征军魂
              今天重温了一下那段历史,一段被经历过的老年人时刻萦绕在脑海无法忘却,被浮躁的中年人忘却,被无知的青年一无所知的历史-----中国远征军。        看完凤凰大视野的那段...
用户244280 2010-06-22 22:13
毛主席词一首
     我很喜欢毛主席的一些诗词,经常去诵读,下面是毛主席的一首词,是红军长征过程中,攻占了娄山关后毛主席写的,词如下:  忆秦娥-娄山关    西风烈   长空雁叫霜晨月   霜晨月   马蹄声碎...
用户244280 2010-06-22 22:04
与君分享---我的一首词
南国冬暖阳花红枝未枯枝未枯好景处处无心留顾 十年漫漫寒窗苦满心抱负却无路却无路愁绪千千泪如雨注...
用户244280 2010-06-22 22:03
我的诗两首
     其一 孤坐仰苍穹星辰月当空又是中秋夜愁绪谁能懂          其二荔园初夏杨柳垂,晓风拂来破静水,怎奈此景无限悲,前途何方愁相随!...
我要评论
1
11
关闭 站长推荐上一条 /2 下一条