tfpwl_lj的个人空间 https://blog.eetop.cn/1638430 [收藏] [复制] [分享] [RSS]

空间首页 动态 记录 日志 相册 主题 分享 留言板 个人资料

日志

Asic设计学习总结-RTL设计

热度 1已有 5549 次阅读| 2018-3-7 19:53 |系统分类:芯片设计

数字电路设计

    RTL设计所需要的理论知识庞杂而繁多,本文所介绍的内容均由个人参阅了许多书籍之后加以整合的,很多内容本人也不是很熟,只是罗列出来作为参考学习的资料。主要有三个部分的内容,第一部分主要是数字电路设计的基础,这是在大学时期应该予以掌握的内容,第二部分是进阶的学习内容附带一个专业方向——MCU,第三部分是有关于各类算法处理的专业知识,需要更多的复合型知识,例如通信方向需要有较好的数学功底傅立叶变换。由于这部分内容实在太多,个人没有能力也没有必要将每一部分的内容都详细的罗列出来,所以这里只是整理出一些需要把握的关键点。至于具体的内容,还请大家按照个人需求,参阅推荐的各类书籍。

一、基础

组合逻辑与时序逻辑:布尔代数,卡诺图,基本与非门,锁存器,触发器,冲突与冒险。——《Verilog HDL高级数字设计》

Verilog语言基础:数值类型,表达式与运算符,assign语句,always语句,if-else语句,case语句,阻塞与非阻塞。——《Verilog HDL 硬件描述语言》

状态机:一段式、二段式、三段式状态机的区别;独热码、二进制码、格雷码的区别及应用场合。——《Verilog HDL高级数字设计》

同步电路和异步电路:两者的本质,异步电路跨时钟域,亚稳态。——IC_learner博客

复位与时钟:同步复位、异步复位、异步复位同步释放的区别,时钟分频——二分频、三分频、任意整数分频,门控时钟,时钟切换。——《深入浅出玩转FPGA,百度文档

数据通路与控制通路:本质上任何数字电路都可以划分为简单的两种类型——控制通路与数据通路,控制通路的核心是状态机,数据通路是各类算术处理算法、并行总线等等。——《Verilog HDL高级数字设计》

Testbench验证:无论什么电路,最终都需要验证其功能的正确性。Testbench的结构主要由a,复位和时钟,b,激励产生电路,c,系统监视器,d,结果比较电路,e,波形产生函数,f,待验证的MODULE等主要模块组成,其中,b是最重要的模块,一切验证都是从激励信号开始的。——《verilogHDL代码风格规范》。初学者推荐使用windowsqustasim 或者modelsim 仿真工具,简单又方便,以后可学习使用VCS+Verdi(比较折腾人)。

二、进阶

代码风格:良好的代码风格很有必要,参考一下企业用的代码风格,有助于个人养成良好的编码习惯。——《企业用verilog代码风格规范》《verilog语言编码风格》

基本常用电路:具备以上庞杂的理论基础之后,需要积累一些常用的基础电路。——《华为Verilog典型电路设计》

接口电路,I2C,UART,SPI接口电路是中小规模芯片常用的对外接口电路,无论是与上位机(PC)通信还是控制其它芯片。I2C从机常用于EEPROM芯片中,主机可以直接使用单片机模拟,ARM单片机直接集成了I2C主机,I2CIP代码网络上有现成的;UART是全双工电路,宏晶单片机通过UART进行烧录,SPI电路最常用于SD卡上。——《Verilog HDL高级数字设计》《通信IC设计(上下册)》有简单的UARTSPI的代码。

RISC,8051 MCU ——IP通过下载EETOP上相关的IP及文档来学习。

 

 

三、专业

数值的表示方法:浮点数,定点数的表示办法——《Verilog HDL高级数字设计》《通信IC设计(上下册)

算术处理算法:浮点数的加法、乘法电路设计。——《Verilog HDL高级数字设计》

通信算法:FIR滤波器,IIR滤波器,傅立叶变换,冗余编码等等各种通信方向必须掌握的。——《通信IC设计(上下册)》《数字信号处理的FPGA实现》

图像处理算法:静态图像,动态图像去噪。——《数字图像处理与图像通信》

   SOCSOC类芯片的组成结构,AMBA总线,IP复用,SV验证。——《Soc设计方法与实现》

四、工具:

文档代码编辑器:GVIMNotpad++

RTL设计规则检查:Nlin,spyglass

五、示例

下列代码为UART全双工串口示例代码,代码来源于《Verilog HDL高级数字设计》,随后的章节将会使用到该示例代码,代码功能细节需结合书籍了解。

下面的代码已经过modelsim验证。

 

UART发送器:

module UART_XMTR #(

  parameter word_size = 8

)(

  output                      Serial_out,

  input  [word_size - 1 : 0]  Data_Bus,

  input                       Load_XMT_datareg,

                              Byte_ready,

                              T_byte,

                              Clock,

                              rst_b

);

  Control_Unit  M0( Load_XMT_DR, Load_XMT_shftreg,start,shift,clear,

                    Load_XMT_datareg,Byte_ready,T_byte,BC_lt_Bcmax,

                    Clock,rst_b);

  Datapath_Unit M1( Serial_out,BC_lt_Bcmax,Data_Bus,Load_XMT_DR,

                    Load_XMT_shftreg,start,shift,clear,Clock,rst_b);

 

endmodule

module Control_Unit #(

  parameter one_hot_count  = 3,

            state_count    = one_hot_count,

            size_bit_count = 3,

            idle           = 3'b001,

            waiting        = 3'b010,

            sending        = 3'b100

           // all_ones       = 9'b1_1111_11111

)(

  output reg Load_XMT_DR,

  output reg Load_XMT_shftreg,

  output reg start,

  output reg shift,

  output reg clear,

 

  input      Load_XMT_datareg,

  input      Byte_ready,

  input      T_byte,

  input      BC_lt_Bcmax,

  input      Clock,

  input      rst_b

);

 

  reg [state_count - 1 : 0]  state, next_state;

 

always @(state, Load_XMT_datareg,Byte_ready,T_byte,BC_lt_Bcmax)

begin:Output_and_next_state

  Load_XMT_DR      = 0;

  Load_XMT_shftreg = 0;

  start            = 0;

  shift            = 0;

  clear            = 0;

  next_state       = idle;

 

case(state)

  idle:    if(Load_XMT_datareg == 1'b1)begin

             Load_XMT_DR = 1;

             next_state = idle;

           end

           else if(Byte_ready == 1'b1)begin

             Load_XMT_shftreg = 1;

             next_state = waiting;

           end

  waiting: if(T_byte == 1) begin

             start = 1;

             next_state =sending;

           end else

             next_state = waiting;

  sending: if(BC_lt_Bcmax) begin

             shift      = 1;

             next_state = sending;

           end

           else begin

             clear = 1;

             next_state = idle;

           end

  default: next_state = idle;

endcase

end

 

always @(posedge Clock,negedge rst_b)

begin: State_Transitions

  if(rst_b == 1'b0)

    state <= idle;

  else

    state <= next_state;

  end

 

endmodule

module Datapath_Unit #(

  parameter word_size      = 8,

            size_bit_count = 3,

            all_ones       = 9'b1_1111_1111

)(

 

  output                 Serial_out,

                         BC_lt_Bcmax,

  input [word_size -1:0] Data_Bus,

  input                  Load_XMT_DR,

  input                  Load_XMT_shftreg,

  input                  start,

  input                  shift,

  input                  clear,

  input                  Clock,

  input                  rst_b

);

 

  reg [word_size -1:0]   XMT_datareg;

  reg [word_size :0]   XMT_shftreg;

  reg [size_bit_count:0] bit_count;

 

assign Serial_out  = XMT_shftreg [0];

assign BC_lt_Bcmax = (bit_count < word_size +1);

 

always @(posedge Clock,negedge rst_b)

  if(rst_b == 0)

  begin

    XMT_shftreg <= all_ones;

    XMT_datareg <= 9'b0_0000_0000;

    bit_count   <= 0;

  end

  else begin:Register_Transfers

    if(Load_XMT_DR == 1'b1)

      XMT_datareg    <= Data_Bus;

    if(Load_XMT_shftreg == 1'b1)

      XMT_shftreg    <= {XMT_datareg,1'b1};

    if(start == 1'b1)

      XMT_shftreg[0] <= 0;

    if(clear == 1'b1)

      bit_count      <= 0;

    if(shift ==1'b1)

    begin

     XMT_shftreg     <= {1'b1,XMT_shftreg[word_size:1]};

     bit_count       <= bit_count + 1;

    end

end

 

endmodule

 

 

UART接收器:

module UART_RCVR #(

  parameter word_size = 8,

           half_word =word_size/2

)(

 

  output [word_size - 1 :0] RCV_datareg,

  output                    read_not_ready_out,

                            Error1,Error2,

  input                     Serial_in,

                            read_not_ready_in,

                            Sample_clk,

                            rst_b

);

 

  Control_Unit2 M0( read_not_ready_out,Error1,Error2,

                clr_Sample_counter,inc_Sample_counter,

                   clr_Bit_counter,inc_Bit_counter,shift,

                 load,read_not_ready_in,Ser_in_0,SC_eq_3,

                 SC_lt_7,BC_eq_8,Sample_clk,rst_b);

  Datapath_Unit2 M1( RCV_datareg,Ser_in_0,SC_eq_3,SC_lt_7,

                 BC_eq_8,Serial_in,clr_Sample_counter,

                  inc_Sample_counter,clr_Bit_counter,

                    inc_Bit_counter,shift,load,Sample_clk,rst_b);

 

endmodule

module Control_Unit2 #(

  parameter word_size      = 8,

            half_word      = word_size/2,

         Num_state_bits = 2,

            idle           = 2'b00,

         starting       = 2'b01,

         receiving      = 2'b10

)(

 

  output reg read_not_ready_out,

             Error1,Error2,

             clr_Sample_counter,

             inc_Sample_counter,

             clr_Bit_counter,

             inc_Bit_counter,

             shift,

             load,

  input      read_not_ready_in,

             Ser_in_0,

             SC_eq_3,

             SC_lt_7,

             BC_eq_8,

             Sample_clk,

             rst_b

);

 

  reg [word_size - 1 :0]         RCV_shftreg;

  reg [Num_state_bits - 1 : 0] state;

  reg [Num_state_bits - 1 : 0]  next_state;

 

always @(posedge Sample_clk or negedge rst_b)

  if(rst_b == 1'b0)

    state <= idle;

  else

    state <= next_state;

 

always @(state,Ser_in_0,SC_eq_3,SC_lt_7,read_not_ready_in)

begin

  read_not_ready_out = 0;

  clr_Sample_counter = 0;

  clr_Bit_counter    = 0;

  inc_Sample_counter = 0;

  inc_Bit_counter    = 0;

  shift              = 0;

  Error1             = 0;

  Error2             = 0;

  load               = 0;

  next_state         = idle;

  case(state)

    idle:    if(Ser_in_0 == 1'b1)

            next_state = starting;

             else

            next_state = idle;

   starting: if(Ser_in_0 ==1'b0)

             begin

               next_state         = idle;

               clr_Sample_counter = 1;

             end else

             if(SC_eq_3 == 1'b1)

          begin

               next_state         = receiving;

               clr_Sample_counter = 1;

             end

          else begin

               inc_Sample_counter = 1;

            next_state         = starting;

             end

     receiving: if(SC_lt_7 == 1'b1)

                begin

                  inc_Sample_counter = 1;

                  next_state         = receiving;

                end

                else begin

                  clr_Sample_counter = 1;

                if(!BC_eq_8)

              begin

               &nb


点赞

发表评论 评论 (2 个评论)

回复 GenesisIC 2021-10-10 19:55
总感觉常见的RTL电路很多很杂,也没有比较标准的参考文件。
回复 tfpwl_lj 2021-10-12 11:11
GenesisIC: 总感觉常见的RTL电路很多很杂,也没有比较标准的参考文件。
其实还好,去一个稍微规整点的公司,内部会有比较详实的常见电路内部IP。

facelist

您需要登录后才可以评论 登录 | 注册

  • 关注TA
  • 加好友
  • 联系TA
  • 0

    周排名
  • 0

    月排名
  • 0

    总排名
  • 0

    关注
  • 74

    粉丝
  • 38

    好友
  • 42

    获赞
  • 52

    评论
  • 4344

    访问数
关闭

站长推荐 上一条 /2 下一条

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-4-18 08:07 , Processed in 0.021702 second(s), 8 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
返回顶部