Kraklog

Day.80 Advavnced Verilog #3 본문

[Harman] 하만 반도체 설계/VerilogHDL

Day.80 Advavnced Verilog #3

Krakens 2023. 11. 13. 09:25
728x90
module my_ram(
  input   [7:0]   	data    ,
  input   [4:0]   	address ,
  input           	wren    ,
  input           	clk     ,
  output reg [7:0]   q        
);
  reg [7:0] mem [0:31];

  always @ (posedge clk) begin
    if (wren)
      mem[address] <= data;
    q <= mem[address];
  end
endmodule

 

`timescale 1ns/1ns
`define CLK_50Mhz 20

module tb_my_ram ();
  reg   [7:0]   data    ;
  reg   [4:0]   address ;
  reg         wren    ;
  reg         clk     ;
  wire  [7:0]  q       ;


  my_ram uMy_ram (
    .data   (data    ), 
    .address(address ), 
    .wren   (wren    ), 
    .clk    (clk     ), 
    .q      (q       ) 
  );
  

  initial begin
    $monitor("[%x] data= %x, address=%x, q=%x", $time, data,address,q);
  end 

  initial begin
    clk = 0;
    forever #(`CLK_50Mhz/2) clk = ~clk;
  end

  initial begin
    data = 8'hA;
    wren = 1'b0;
    address = 5'h0;
    #30;
    data = 8'hA;
    #20;
    address = 5'h1;
    data = 8'hb;
    #10;
    address = 5'h2;
    #10;
    wren = 1'b1;
    address = 5'h3;
     
  end 

endmodule

 

`define DBUS_SIZE 8
`define ABUS_SIZE 5

module my_ram (
  input                   clk     ,
  input                   wren    ,
  input   [`ABUS_SIZE-1:0] address ,
  input   [`DBUS_SIZE-1:0] data    ,
  output  [`DBUS_SIZE-1:0] q        
);

  reg [`DBUS_SIZE-1:0] mem[0:2**`ABUS_SIZE-1]//2^5 = 32  bit

  always @(posedge clk) begin
    if (wren)
      mem[address] <= data;

    q<=mem[address];
  end


// means, 
/*
  always @(posedge clk) begin
    if (wren)
      mem[address] <= data;
  end
  always @ (posedge clk) begin
    q<=mem[address];
  end 
*/
endmodule​

 

 

 

 

`timescale 1ns/1ns
`define DBUS_SIZE 8
`define ABUS_SIZE 5
`define CLK_50MHZ 20

module tb_my_ram2();
  reg                     clk     ;
  reg                     wren    ;
  reg   [`ABUS_SIZE-1:0]  address ;
  reg   [`DBUS_SIZE-1:0]  data    ;
  wire  [`DBUS_SIZE-1:0]  q       ;

  my_ram2 uMy_ram (
    .clk    (clk    ) ,
    .wren   (wren   ) ,
    .address(address) ,
    .data   (data   ) ,
    .q      (q      )  
  );

  initial 
    fork
      clk_gen();
      cntl_gen();
      data_gen();  
    join

  task clk_gen;
    begin
      clk = 1'b0;
      forever #(`CLK_50MHZ/2) clk = ~clk;
    end  
  endtask

  task cntl_gen;
    begin
      wren    = 1'b0;
      address = 5'b0;
      repeat(3) @(negedge clk);

      address = 5'h5;
      @(negedge clk);
      
      address = 5'h6;
      @(negedge clk);
      
      wren = 1'b1;
      address = 5'h5;
      @(negedge clk);

      address = 5'h6;
    end
  endtask

  task data_gen;
    begin
      data = 8'hAA;
      repeat(5) @(negedge clk);
      data = 8'h55;
    end    
  endtask
  
endmodule

 

`define DBUS_SIZE 8
`define ABUS_SIZE 5

module my_ram2 (
  input                   	clk     ,
  input                   	wren    ,
  input   [`ABUS_SIZE-1:0]  address ,
  input   [`DBUS_SIZE-1:0]  data    ,
  output reg [`DBUS_SIZE-1:0]  q        
);

  reg [`DBUS_SIZE-1:0] mem[0:2**`ABUS_SIZE-1];//2^5 = 32  bit
  reg [`DBUS_SIZE-1:0] mem_out;
  
  
  always @(posedge clk) begin
    if (wren)
      mem[address] <= data;
  end
  always @ (posedge clk) begin
    mem_out <= mem[address]; // pipeline
    q <= mem_out[address];
  end 
  // means, 
  /*always @ (posedge clk) begin
    if (wren)
      mem[address] <= data;
    q <= mem[address];
  end */


endmodule

Pipe line 을 활용해서 클럭을 하나 미뤄서 출력을 보게 만들었음.

 

 

`timescale 1ns/1ns
`define CLK_50Mhz 20

module tb_my_ram ();
  reg   [7:0]   data    ;
  reg   [4:0]   address ;
  reg         wren    ;
  reg         clk     ;
  wire  [7:0]  q       ;


  my_ram uMy_ram (
    .data   (data    ), 
    .address(address ), 
    .wren   (wren    ), 
    .clk    (clk     ), 
    .q      (q       ) 
  );
  

  initial begin
    $monitor("[%x] data= %x, address=%x, q=%x", $time, data,address,q);
  end 

  initial begin
    clk = 0;
    forever #(`CLK_50Mhz/2) clk = ~clk;
  end

  initial begin
    wren= 1;
    forever #(`CLK_50Mhz) wren = ~wren;
  end

 initial begin
    address = 5'h0;
    forever #30 begin
      address <= address + 1;
    end
  end

  initial begin
    data = 8'h0;
    forever #40 begin
      data <= data +1;
    end
  end

endmodule

 

자동으로 1씩 늘어나게 코딩
wren 클럭에 따라 3 6 9 ... 값들만 할당이 되어 나타난다.


module my_shift (
  input             clk     ,
  input             aclr_n  ,
  input             enable  ,
  input             shiftin ,
  output  reg [7:0] q        
);

  always @ (posedge clk, negedge aclr_n) 
    if (!aclr_n)
      q[7:0] <= 0;
    else if (enable)
      q[7:0] <= {q[6:0],shiftin};
endmodule

`timescale 1ns/1ns
`define CLK_50Mhz 20


module tb_my_shift();
  reg         clk     ;
  reg         aclr_n  ;
  reg         enable  ;
  reg         shiftin ;
  wire  [7:0] q       ;

 my_shift uMy_shift (
    .clk    (clk    ),
    .aclr_n (aclr_n ),
    .enable (enable ),
    .shiftin(shiftin),
    .q      (q      ) 
);

initial fork
  clk_gen();
join

task clk_gen; 
  begin
    clk = 0;
    forever #(`CLK_50Mhz/2) clk = ~clk;
  end
endtask

  always @(posedge clk, negedge aclr_n) begin
  end

  initial begin
    aclr_n  = 1'b0;
   
    
    #20;
    enable  = 1'b0;
    aclr_n = 1'b1;
    #10;
    enable = 1'b1;
    shiftin = 1'b0;
    #10
    shiftin = 1'b1;
    #10;


  end

endmodule

module my_shift2 (
  input             clk     ,
  input             aclr_n  ,
  input             enable  ,
  input             shiftin ,
  output  reg [7:0] q        
);

  always @ (posedge clk, negedge aclr_n) 
    if (!aclr_n)
      q[7:0] <= 0;
    else if (enable)
      q[7:0] <= {q[6:0],shiftin};
endmodule

`timescale 1ns/1ns
`define CLK_50Mhz 20


module tb_my_shift2();
  reg         clk     ;
  reg         aclr_n  ;
  reg         enable  ;
  reg         shiftin ;
  wire  [7:0] q       ;

 my_shift2 uMy_shift (
    .clk    (clk    ),
    .aclr_n (aclr_n ),
    .enable (enable ),
    .shiftin(shiftin),
    .q      (q      ) 
);

initial fork
  clk_gen();
  reset_gen();
  ctrl_gen();
  data_gen();
join

task clk_gen; 
  begin
    clk = 0;
    forever #(`CLK_50Mhz/2) clk = ~clk;
  end
endtask

task reset_gen;
  begin
    aclr_n =1'b1;
    repeat(2) @(negedge clk);
     aclr_n =1'b0;
    repeat(2) @(negedge clk); 
    aclr_n =1'b1;
  end
endtask

task ctrl_gen;
  begin
    enable = 1'b0;
    repeat (6) @(negedge clk);
    enable = 1'b1;
  end
endtask

task data_gen;
  begin
    shiftin=1'b0;
    repeat(5)
    shiftin=1'b1;
    @(negedge clk);
    @(negedge clk);
    shiftin=1'b0;
    @(negedge clk);
    @(negedge clk);
    shiftin=1'b1;
    @(negedge clk);
    shiftin=1'b0;
    @(negedge clk);
    shiftin=1'b1;
    @(negedge clk);
    shiftin=1'b1;
    @(negedge clk);
  end
endtask


endmodule

728x90