【【FIFO to multiplier to RAM的 verilog 代码 和 testbnench 】】

FIFO to multiplier to RAM的 verilog 代码 和 testbnench

只完成了单个数据的传输 大数据需要修改 tb 或者基本连线

FIFO.v

c 复制代码
//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

multiplier.v

c 复制代码
module uumultiplier #(
    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+NUMBER2 : 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

RAM.v

c 复制代码
//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

c 复制代码
module dig_top #(
  parameter        FIFO_WIDTH        =        8                       ,
  parameter        FIFO_DEPTH        =        8                       ,
  parameter        FIFO_ADDR_WIDTH   =        clogb2(FIFO_DEPTH)      ,
  parameter        NUMBER1           =        8                       ,
  parameter        NUMBER2           =        2                       ,
  parameter        RAM_WIDTH         =        NUMBER1+NUMBER2+1       ,
  parameter        RAM_DEPTH         =        8                       ,
  parameter        RAM_ADDR_WIDTH    =        clogb2(RAM_DEPTH)
)(
  input                                       sys_clk                 ,
  input                                       sys_rst_n               ,
  input                                       wr_en                   ,
  input                                       rd_en                   ,
  input            [FIFO_WIDTH-1 : 0]         din                     ,
  input                                       RAM_rd_en               ,
  input            [RAM_ADDR_WIDTH-1 : 0]     wr_address              ,
  input            [RAM_ADDR_WIDTH-1 : 0]     rd_address              ,
  output    wire   [RAM_WIDTH-1 : 0]          dout 
);


//=============================================================================\
//       define parameter  and  internal  signals                              \
//=============================================================================\

wire     full  ;
wire   empty  ;
wire    [FIFO_WIDTH-1 : 0]   dout1 ;
wire     finish_en        ;
wire    [RAM_WIDTH-1 : 0 ]      dout2  ;





//===============================================================================\
//                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



FIFO_syn # (
    .WIDTH(FIFO_WIDTH),
    .DEPTH(FIFO_DEPTH),
    .ADDR_WIDTH(FIFO_ADDR_WIDTH)
  )
  FIFO_syn_inst (
    .sys_clk(sys_clk),
    .sys_rst_n(sys_rst_n),
    .wr_en(wr_en),
    .rd_en(rd_en),
    .din(din),
    .full(full),
    .empty(empty),
    .dout(dout1)
  );

  uumultiplier # (
    .NUMBER1(NUMBER1),
    .NUMBER2(2'b10)
  )
  uumultiplier_inst (
    .input1(dout1),
    .input2(2'b10),
    .clk(sys_clk),
    .rst_n(sys_rst_n),
    .begin_en(rd_en),
    .finish_en(finish_en),
    .out(dout2)
  );


  RAM # (
    .WIDTH(RAM_WIDTH),
    .DEPTH(RAM_DEPTH),
    .ADD_WIDTH(RAM_ADDR_WIDTH)
  )
  RAM_inst (
    .wr_clk(sys_clk),
    .rd_clk(sys_clk),
    .wr_en(finish_en),
    .rd_en(RAM_rd_en),
    .din(dout2),
    .wr_address(wr_address),
    .dout(dout),
    .rd_address(rd_address)
  );


endmodule 

top_tb.v

c 复制代码
`timescale 1ns/1ns
module top_tb #(
  parameter        FIFO_WIDTH        =        4                       ,
  parameter        FIFO_DEPTH        =        8                       ,
  parameter        FIFO_ADDR_WIDTH   =        3      ,
  parameter        NUMBER1           =        4                       ,
  parameter        NUMBER2           =        2                       ,
  parameter        RAM_WIDTH         =        7       ,
  parameter        RAM_DEPTH         =        8                       ,
  parameter        RAM_ADDR_WIDTH    =        3
);
reg                                       sys_clk                ;
reg                                       sys_rst_n              ;
reg                                       wr_en                  ;
reg                                       rd_en                  ;
reg            [FIFO_WIDTH-1 : 0]         din                    ;
reg                                       RAM_rd_en              ;
reg            [RAM_ADDR_WIDTH-1 : 0]     wr_address             ;
reg            [RAM_ADDR_WIDTH-1 : 0]     rd_address             ;
wire           [RAM_WIDTH-1 : 0]          dout                   ;
reg          [11:0 ] cnt  ;


dig_top # (
    .FIFO_WIDTH(FIFO_WIDTH),
    .FIFO_DEPTH(FIFO_DEPTH),
    .FIFO_ADDR_WIDTH(FIFO_ADDR_WIDTH),
    .NUMBER1(NUMBER1),
    .NUMBER2(NUMBER2),
    .RAM_WIDTH(RAM_WIDTH),
    .RAM_DEPTH(RAM_DEPTH),
    .RAM_ADDR_WIDTH(RAM_ADDR_WIDTH)
  )
  dig_top_inst (
    .sys_clk(sys_clk),
    .sys_rst_n(sys_rst_n),
    .wr_en(wr_en),
    .rd_en(rd_en),
    .din(din),
    .RAM_rd_en(RAM_rd_en),
    .wr_address(wr_address),
    .rd_address(rd_address),
    .dout(dout)
  );

  always   #5   sys_clk  =  ~sys_clk    ;

  initial	begin
    sys_clk		=	1;
    sys_rst_n		=	0;
    #100
    sys_rst_n		=	1;
  end
  always #10 	sys_clk	=	~sys_clk;
  initial  begin 
    sys_clk = 0 ;
    sys_rst_n = 1 ;
    wr_en = 0  ; 
    rd_en = 0 ;
    wr_address = 1 ; 
    rd_address = 1 ;





    #10

    sys_rst_n = 0;

    #10
    sys_rst_n = 1 ;

    #10
    // next is write 
    wr_en  =   1  ;
    rd_en  =   1  ; 

    din = 2 ;
    
// RAM  read 
    RAM_rd_en = 1 ;
  
  end 

endmodule 
相关推荐
武汉凯迪正大电气12 小时前
武汉凯迪正大—变压器空负载特性参数测试仪 变压器容量及损耗参数测试仪
fpga开发
IM_DALLA12 小时前
【Verilog学习日常】—牛客网刷题—Verilog快速入门—VL16
学习·fpga开发
IM_DALLA12 小时前
【Verilog学习日常】—牛客网刷题—Verilog快速入门—VL18
学习·fpga开发
芯冰乐12 小时前
综合时如何计算net delay?
后端·fpga开发
落雨无风14 小时前
quartus pin 分配(三)
fpga开发
cycf17 小时前
深入浅出通信原理
fpga开发·信息与通信
IM_DALLA1 天前
【Verilog学习日常】—牛客网刷题—Verilog快速入门—VL21
学习·fpga开发
皇华ameya2 天前
AMEYA360:村田电子更适合薄型设计应用场景的3.3V输入、12A输出的DCDC转换IC
fpga开发
千穹凌帝2 天前
SpinalHDL之结构(二)
开发语言·前端·fpga开发
一口一口吃成大V2 天前
FPGA随记——FPGA时序优化小经验
fpga开发