【【硬件数据流从control to FIFO1 to adder to RAM to FIFO2 to control2的 verilog 代码实现 ---- 初版 】】

硬件数据流从control to FIFO1 to adder to RAM to FIFO2 to control2的 verilog 代码实现 ---- 初版

这是初版的代码 可以提供 一个大概的思路
如果想要处理大数据的话 把 BRAM需要修改 我先做了一个简单的环路 将 地址始终 固定为1
还有 里面内部的各种使能信号 我尽可能 的 完成贴近 握手协议 但是 对于只 传递 一个数据位
并不需要考虑太多此处的问题
我们只展示初步的代码

adder.v

module adder #(
    parameter       NUMBER1      =      8                ,
    parameter       NUMBER2      =      8
  )(
    input  [NUMBER1-1 : 0]                  input1       ,
    input  [NUMBER2-1 : 0]                  input2       ,
    input                                   clk          ,
    input                                   rst_n        ,
    input                                   begin_en     ,
    output  reg                             finish_en    ,
    output  reg [NUMBER1-1 : 0]       out
  );


  //======================================================================================\
  //                define parameter  and  internal signal                                \
  //======================================================================================\
  reg [1:0] LCD = 2'b10 ;
  reg [1:0] LCD1 ;

  //==========================================================================================\
  //                     next   is  main  code                                                 \\
  //===========================================================================================\\

  always@(posedge clk or negedge rst_n)
  begin

    if(rst_n == 0)
    begin
      out <= 0 ;
    end

    else
      LCD1 <= LCD  ;
  end



  always@(posedge clk or negedge rst_n)
  begin
    if(rst_n == 0)
    begin
      out <= 0 ;
    end
    else  if(begin_en && finish_en )
    begin

      out <= input1 + input2 ;
      LCD <= {LCD[0],LCD[1]} ;
    end
    else
      out <= out ;
  end



  always@(posedge clk or negedge rst_n)
  begin
    if(rst_n == 0)
    begin
      finish_en <= 1'b1 ;
    end
    else if(LCD == LCD1)
    begin
      finish_en <= 1'b1 ;
    end
    else
      finish_en <= 1'b0 ;
  end


endmodule

control.v

module control #(
    parameter               WIDTH      =      8                  
    //parameter               TKEEP      =      clogb2(WIDTH)
  )(
    input                      sys_clk        ,
    input                      sys_rst_n      ,
   // input      [TKEEP-1 : 0]   s_keep         ,
    input                      tvaild         ,
    input      [WIDTH-1 : 0]   din            ,
    output  reg                   tready         ,
    output  reg   [WIDTH-1 : 0]   dout           ,
    output  reg                   wr_en          ,
    output  reg                   rd_en
  );
  //=============================================================================\\
  //        define  parameter  and internal  signals                             \\
  //==============================================================================\\
  reg [1:0] LCD = 2'b10 ;
  reg [1:0] LCD1  ;


  //===============================================================================\\
  //                         next is  main code                                    \\
  //================================================================================\\


  //this is function
  function integer clogb2 ;
    input [31:0] value ;
    begin
      value = value - 1 ;
      for(clogb2=0;value>0;clogb2=clogb2+1)
        value = value >> 1 ;
    end
  endfunction


  //this is build to control for handshake
  always@(posedge sys_clk or negedge sys_rst_n)
  begin
    if(sys_rst_n == 0)
    begin
      LCD1 <= 0 ;
    end
    else
      LCD1 <= LCD ;
  end


  // this is for  output
  always@(posedge sys_clk or negedge sys_rst_n)
  begin
    if(sys_rst_n == 0)
    begin
      dout <= 0;
    end
    else if( tvaild  && tready )
    begin
      dout <= din ;
      LCD <= {LCD[0],LCD[1]}  ;
    end
    else
    begin
      dout <= dout ;
    end
  end

  // this is used to build tready
  always@(posedge sys_clk or negedge sys_rst_n)
  begin
    if(sys_rst_n == 0)
    begin
      tready <= 1'b1 ;
    end
    else if(LCD == LCD1)
    begin
      tready <= 1'b1 ;
    end
    else
      tready<= 1'b0 ;
  end

  //this is used to wr_en   or  rd_en
  always@(posedge sys_clk or negedge sys_rst_n)
  begin
    if(sys_rst_n == 0)
    begin
      wr_en <= 0 ;
      //rd_en <= 0 ;
    end
    else
    begin
      wr_en<= (tready == 1) ? 1 : 0 ;
     // rd_en <= 1 ;
    end
  end

// i want to build a way let if write that we read 
//this is used to rd_en 
  always@(posedge sys_clk or negedge sys_rst_n)
  begin
    if(sys_rst_n == 0)
    begin
      rd_en <= 0 ;
    end
    else
    begin
      rd_en <= (wr_en == 1) ? 1 : 0  ;
    end
  end
endmodule

control2.v

module control2 #(
    parameter              WIDTH      =      8
    // parameter              KEPBIT     =      count(WIDTH)
  )(
    input                          sys_clk         ,
    input                          sys_rst_n       ,
    input                          tready1         ,     //  this control2 is used to get from DMA read
    input      [WIDTH-1 : 0]       din             ,
    // next is output four output

    output  reg                       s_tvaild       ,
    output  reg   [WIDTH-1 : 0]       s_dout         ,
    output  reg                        s_last
    //output  reg                    s_tlast        ,
    // output  reg   [KEPBIT-1:0]     s_tkeep
  );
  //=============================================================================\\
  //        define  parameter  and internal  signals                             \\
  //==============================================================================\\
  reg [1:0]             LCD = 2'b10 ;
  reg [1:0]             LCD1        ;
  reg [WIDTH-1 : 0]     dout1       ;




  //===============================================================================\\
  //                         next is  main code                                    \\
  //================================================================================\\


  //this is function
  // function integer count ;
  // input [31:0] value ;
  //  begin
  //   for(count=0;value>0;count=count+1)
  //      value = value >> 8 ;
  //  end
  // endfunction




  //this is build to control for handshake
  always@(posedge sys_clk or negedge sys_rst_n)
  begin
    if(sys_rst_n == 0)
    begin
      LCD1 <= 0 ;
    end
    else
      LCD1 <= LCD ;
  end



  // this is for  output  s_dout
  always@(posedge sys_clk or negedge sys_rst_n)
  begin
    if(sys_rst_n == 0)
    begin
      s_dout <= 0;
    end
    else if( s_tvaild  && tready1 )
    begin
      s_dout <= din ;
      LCD <= {LCD[0],LCD[1]}  ;
    end
    else
    begin
      s_dout <= s_dout ;
    end
  end


  // this is used to build s_tvaild
  always@(posedge sys_clk or negedge sys_rst_n)
  begin
    if(sys_rst_n == 0)
    begin
      s_tvaild <= 1'b1 ;
    end
    else if(LCD == LCD1)
    begin
      s_tvaild <= 1'b1 ;
    end
    else
      s_tvaild<= 1'b0 ;
  end


  // this is what we add to give out

  always@(posedge sys_clk  or negedge sys_rst_n)
  begin
    if(sys_rst_n == 0)
    begin
      s_last <= 0 ;
    end
    else if(s_dout == dout1 )
    begin
      s_last <= 1 ;
    end
    else
      s_last <= 0 ;

  end

  // this is what we add to give last
  always@(posedge sys_clk  or negedge sys_rst_n)
  begin
    if(sys_rst_n == 0)
    begin
      dout1 <= 0 ;
    end
    else
      dout1 <= s_dout ;
  end



endmodule

FIFO1.v

//synchronous  fifo
module FIFO_syn #(
    parameter 		WIDTH		=	16,                    //  the fifo wide
    parameter 		DEPTH		=	1024,                  //  deepth
    parameter 		ADDR_WIDTH	=	clogb2(DEPTH)        //  bit wide
 //   parameter 		PROG_EMPTY	=	100,                   //  this what we set to empty
  //  parameter 		PROG_FULL	=	800                     //  this what we set to full
  )
  (
    input   sys_clk                    ,
    input   sys_rst_n                    ,
    input   wr_en                      ,
    input   rd_en                      ,
    input   [WIDTH-1: 0] din           ,
    output  reg  full                  ,
    output  reg  empty                 ,         ///  1 is  real empty  0 is no empty
    output  reg  [WIDTH-1:0]  dout     
  );

  //========================================================================================//
  //                              define parameter and internal signals                     //
  //======================================================================================//
  reg [WIDTH-1 : 0]          ram[DEPTH-1 : 0]   ;     // this we set a  15:0   total 1024 number ram
  reg [ADDR_WIDTH-1 : 0]     wr_addr            ;     // this is  write pointer
  reg [ADDR_WIDTH-1 : 0]     rd_addr            ;     // this is  read  pointer
  reg [ADDR_WIDTH-1 : 0]     fifo_cnt           ;

  //=========================================================================================//
  //                             next  is  main code                                           //
  //=========================================================================================//

  //  we  set a function  let me to  count    the number
  function integer clogb2;                     //  remember integer has  symbol  reg  has no symbol
    input[31:0]value;
    begin
      value=value-1;
      for(clogb2=0;value>0;clogb2=clogb2+1)
        value=value>>1;
    end
  endfunction
  //   this  you can see from the  PPT 5-74


  //===================================================  next  is used to read

  always@(posedge sys_clk or negedge sys_rst_n)
  begin
    if(sys_rst_n == 0)
      rd_addr		<=		{ADDR_WIDTH{1'b0}};
    else if(rd_en && !empty)
    begin
      rd_addr		<=		rd_addr+1'd1;
      dout		<=		ram[rd_addr];
    end
    else
    begin
      rd_addr		<=		rd_addr;
      dout		<=		dout;
    end
  end




  //===================================================  next  is used to write
  always@(posedge sys_clk  or negedge sys_rst_n)
  begin
    if(sys_rst_n == 0)
    begin
      wr_addr         <=    {ADDR_WIDTH{1'b0}}   ;         //  this  let pointer to zero
    end
    else if( wr_en  &&  !full )
    begin   // no full and  wr_en   and  whether to write prog_full there
      wr_addr          <=    wr_addr + 1'b1  ;
      ram[wr_addr]     <=    din             ;
    end
    else
      wr_addr          <=    wr_addr         ;
  end





  //==============================================================  next  is  used to set fifo_cnt
  always@(posedge sys_clk  or negedge sys_rst_n )
  begin
    if(sys_rst_n == 0)
    begin
      fifo_cnt  <=  {ADDR_WIDTH{1'b0}};
    end
    else if(wr_en &&  !full  &&  !rd_en)
    begin
      fifo_cnt  <=   fifo_cnt + 1'b1 ;
    end
    else if(rd_en && !empty && !wr_en)
    begin
      fifo_cnt  <=  fifo_cnt - 1'b1 ;
    end
    else
      fifo_cnt  <=  fifo_cnt ;
  end


  //==========================================================     next is empty
  //  we set  counter  so  when the count is zero  empty
  always@(posedge sys_clk  or negedge sys_rst_n)
  begin
    if(sys_rst_n == 0)
    begin
      empty <= 1'b1 ;      //  begin  we set empty to high
    end
    // there is  two possibilties first no write fifo_cnt is all zero
    //second is no write it will be change to zero  is just a will empty signal
    else
      empty <=  (!wr_en && (fifo_cnt[ADDR_WIDTH-1:1] == 'b0))&&((fifo_cnt[0] == 1'b0) || rd_en);
  end



  //============================================================  next is full

  always@(posedge sys_clk or negedge sys_rst_n)
  begin
    if(sys_rst_n == 0 )
      full	<=	1'b1;//reset:1
    else
      full	<=	(!rd_en	&&	(fifo_cnt[ADDR_WIDTH-1:1]=={(ADDR_WIDTH-1){1'b1}})) && ((fifo_cnt[0] == 1'b1) || wr_en);
  end

endmodule

RAM.v

//DUal ended RAM 
module RAM #(
    parameter     WIDTH      =     8   ,
    parameter     DEPTH      =     16  ,
    parameter     ADD_WIDTH  =     clogb2(DEPTH) 
)(
    input                       wr_clk         ,
    input                       rd_clk         ,
    input                       wr_en          ,
    input                       rd_en          ,
    input      [WIDTH-1 : 0 ]      din         ,
    input      [ADD_WIDTH-1 : 0]   wr_address  ,
    output reg [WIDTH-1 : 0 ]      dout        ,
    input      [ADD_WIDTH-1 : 0]   rd_address  
);


//==================================================================================\\
//       define  parameter   and  internal   signal                                 \\
//==================================================================================\\

reg [WIDTH - 1 : 0 ] ram [DEPTH - 1 : 0] ; 





//==================================================================================\\
//                              next is  main code                                  \\
//==================================================================================\\


function integer clogb2  ;
input [31:0] value  ;
begin 
    value = value - 1 ;
    for(clogb2 = 0 ; value > 0 ; clogb2 = clogb2 + 1)
    value = value >> 1 ; 
end
endfunction 


// write  
always@(posedge wr_clk) 
begin 
    if(wr_en) begin 
        ram[wr_address] <= din ;
    end
end 

//read 
always@(posedge rd_clk) 
begin 
    if(rd_en) begin 
        dout <= ram[rd_address] ;
    end
end 
endmodule 

top.v

module dig_top #(
    parameter            CONTROL1_WIDTH        =         8                      ,
    parameter            FIFO1_WIDTH           =         8                      ,
    parameter            FIFO1_DEPTH           =         1024                   ,
    parameter            FIFO1_ADDR_WIDTH      =         clogb2(FIFO1_DEPTH)    ,
    parameter            NUMBER1               =         8                      ,
    parameter            NUMBER2               =         2                      ,
    parameter            RAM_WIDTH             =         8                      ,
    parameter            RAM_DEPTH             =         8                      ,
    parameter            RAM_ADDR_WIDTH        =         clogb2(RAM_DEPTH)      ,
    parameter            FIFO2_WIDTH           =         8                      ,
    parameter            FIFO2_DEPTH           =         1024                   ,
    parameter            FIFO2_ADDR_WIDTH      =         clogb2(FIFO1_DEPTH)    ,
    parameter            CONTROL2_WIDTH        =         8
  )(
    input                                      sys_clk    ,
    input                                      sys_rst_n  ,
    input                                      tvaild     ,
    output                                     tready     ,
    input     [CONTROL1_WIDTH-1 : 0]           din        ,
    output    [CONTROL2_WIDTH-1 : 0]           dout       ,
    output                                     s_tvaild   ,
    input                                      s_ready    ,
    output                                     s_last      
  );

  //====================================================================================\\
  //                            define  parameter or  internal  signals                 \\
  //====================================================================================\\

  //control1 
  wire                             wr_en         ;
  wire                             rd_en         ;
  wire   [CONTROL1_WIDTH - 1 : 0]  dout_control  ; 
  wire                             full          ;
  wire                             empty         ;
  wire   [FIFO1_WIDTH - 1 : 0]     dout_FIFO     ;
  wire                             finish_en     ;
  wire   [RAM_WIDTH - 1 : 0]       dout_adder    ;
  wire   [RAM_WIDTH - 1 : 0]       dout_RAM      ;
  wire                             RAM_rd_en1    ;
  wire                             RAM_rd_en     ;
  wire                             FIFO2_full    ;
  wire                             FIFO2_empty   ;
  wire   [FIFO2_WIDTH - 1 : 0]     dout_FIFO2    ;











  //========================================================================================\\
  //                       next  is  main code                                              \\
  //=========================================================================================\\
  function integer clogb2 ;
    input [31:0] value ;
    begin
      value = value - 1 ;
      for(clogb2 = 0 ; value > 0 ; clogb2 = clogb2 + 1)
        value = value >> 1 ;
    end
  endfunction

  //next is control1 

control#(
    .WIDTH      ( CONTROL1_WIDTH )
)u_control(
    .sys_clk    ( sys_clk            ),
    .sys_rst_n  ( sys_rst_n          ),
    .tvaild     ( tvaild             ),     // input 
    .din        ( din                ),     // input 
    .tready     ( tready             ),     // output  
    .dout       ( dout_control       ),     //wire
    .wr_en      ( wr_en              ),    //wire   we set just tready == 1 wr_en 
    .rd_en      ( rd_en              )    //wire    we set always in 1 
);

//next is FIFO1
FIFO_syn#(
    .WIDTH      ( FIFO1_WIDTH ),
    .DEPTH      ( FIFO1_DEPTH ),
    .ADDR_WIDTH ( FIFO1_ADDR_WIDTH )
)u_FIFO_syn(
    .sys_clk    ( sys_clk             ),
    .sys_rst_n  ( sys_rst_n           ),
    .wr_en      ( wr_en               ),
    .rd_en      ( rd_en               ),
    .din        ( dout_control        ),     // from control     
    .full       ( full                ),
    .empty      ( empty               ),
    .dout       ( dout_FIFO           )     // this  is  from  FIFO send to adder input1
);

// next is adder
adder#(
    .NUMBER1    ( NUMBER1 ),
    .NUMBER2    ( NUMBER2 )
)u_adder(
    .input1     ( dout_FIFO     ),        // this is from FIFO 
    .input2     ( 2'b10         ),
    .clk        ( sys_clk       ),
    .rst_n      ( sys_rst_n     ),
    .begin_en   ( rd_en         ),         //  this is connect rd_en 
    .finish_en  ( finish_en     ),
    .out        ( dout_adder    )         //  this is send to bram 
);


// there we should add one change the RAM_rd_en  







// something should be add 
// becasuse we just send one number we should not think the module whether address


// next is BRAM  
RAM#(
    .WIDTH       ( RAM_WIDTH      ),
    .DEPTH       ( RAM_DEPTH      ),
    .ADD_WIDTH   ( RAM_ADDR_WIDTH )
)u_RAM(
    .wr_clk      ( sys_clk     ),
    .rd_clk      ( sys_clk     ),
    .wr_en       ( finish_en   ),
    .rd_en       ( 1           ),      //  i think  we should set something   
    .din         ( dout_adder  ),      //  the out is from adder
    .wr_address  ( 1           ),       //    i just set one way so we put address just a set value 
    .dout        ( dout_RAM    ),
    .rd_address  ( 1           )
);


//next is FIFO2  

FIFO_syn#(
    .WIDTH      ( FIFO2_WIDTH ),
    .DEPTH      ( FIFO2_DEPTH ),
    .ADDR_WIDTH ( FIFO2_ADDR_WIDTH )
)u_FIFO_syn2(
    .sys_clk    ( sys_clk          ),
    .sys_rst_n  ( sys_rst_n        ),
    .wr_en      ( 1                ),         //  we should pay attention to this wr_en or rd_en 
    .rd_en      ( 1                ),
    .din        ( dout_RAM         ),
    .full       ( FIFO2_full       ),
    .empty      ( FIFO2_empty      ),
    .dout       ( dout_FIFO2       )
);


// next is control 
control2#(
    .WIDTH      ( CONTROL2_WIDTH )
)u_control2(
    .sys_clk    ( sys_clk    ),
    .sys_rst_n  ( sys_rst_n  ),
    .tready1    ( s_ready    ),
    .din        ( dout_FIFO2        ),
    .s_tvaild   ( s_tvaild   ),
    .s_dout     ( dout     ),
    .s_last     ( s_last     )
);

endmodule 

top_tb.v

`timescale 1ns/1ps
module top_tb #(
    parameter            CONTROL1_WIDTH        =         4                      ,
    parameter            FIFO1_WIDTH           =         4                      ,
    parameter            FIFO1_DEPTH           =         8                   ,
    parameter            FIFO1_ADDR_WIDTH      =         3    ,
    parameter            NUMBER1               =         4                      ,
    parameter            NUMBER2               =         2                      ,
    parameter            RAM_WIDTH             =         4                      ,
    parameter            RAM_DEPTH             =         8                      ,
    parameter            RAM_ADDR_WIDTH        =         3      ,
    parameter            FIFO2_WIDTH           =         4                      ,
    parameter            FIFO2_DEPTH           =         8                  ,
    parameter            FIFO2_ADDR_WIDTH      =         3    ,
    parameter            CONTROL2_WIDTH        =        4
);
reg                                      sys_clk         ;
reg                                      sys_rst_n       ;
reg                                      tvaild          ;
wire                                     tready          ;
reg     [CONTROL1_WIDTH-1 : 0]           din             ;
wire    [CONTROL2_WIDTH-1 : 0]           dout            ;
wire                                     s_tvaild        ;
reg                                      s_ready         ;
wire                                     s_last          ; 



dig_top#(
    .CONTROL1_WIDTH   ( CONTROL1_WIDTH ),
    .FIFO1_WIDTH      ( FIFO1_WIDTH ),
    .FIFO1_DEPTH      ( FIFO1_DEPTH ),
    .FIFO1_ADDR_WIDTH ( FIFO1_ADDR_WIDTH ),
    .NUMBER1          ( NUMBER1 ),
    .NUMBER2          ( NUMBER2 ),
    .RAM_WIDTH        ( RAM_WIDTH ),
    .RAM_DEPTH        ( RAM_DEPTH ),
    .RAM_ADDR_WIDTH   ( RAM_ADDR_WIDTH ),
    .FIFO2_WIDTH      ( FIFO2_WIDTH ),
    .FIFO2_DEPTH      ( FIFO2_DEPTH ),
    .FIFO2_ADDR_WIDTH ( FIFO2_ADDR_WIDTH ),
    .CONTROL2_WIDTH   ( CONTROL2_WIDTH  )
)u_dig_top(
    .sys_clk          ( sys_clk          ),
    .sys_rst_n        ( sys_rst_n        ),
    .tvaild           ( tvaild           ),
    .tready           ( tready           ),
    .din              ( din              ),
    .dout             ( dout             ),
    .s_tvaild         ( s_tvaild         ),
    .s_ready          ( s_ready          ),
    .s_last           ( s_last           )
);

//input                                      sys_clk    ,
//input                                      sys_rst_n  ,
//input                                      tvaild     ,
//input     [CONTROL1_WIDTH-1 : 0]           din        ,
//input                                      s_ready    ,

always  #5 sys_clk = ~sys_clk      ;
initial begin 
    sys_clk   =   0  ;
    sys_rst_n  =  1 ;
    tvaild =  0 ;
    din = 4'b0010 ;
    s_ready = 0 ;


    #10
    sys_rst_n   =  1  ; 
    
    #10 
    sys_rst_n   =  0  ; 

    #10
    sys_rst_n   =  1  ; 
    tvaild =  1;
    din = 4'b0110 ;
    s_ready = 1 ;


end
endmodule 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值