⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 generate_ddr_sim_model.pl

📁 基于NIOS II的ddr2控制器,配有详细的文档,经验证后可使用.
💻 PL
📖 第 1 页 / 共 4 页
字号:
                   ],
              }),
           );           
       } # if local_burst_length > 1
             
        # Assign Outputs:
        # if ($mem_mask_width > 1) {
        #     for (0 .. ($mem_mask_width - 1)) {
        #         $module->add_contents
        #             (
        #              e_assign->new
        #              (
        #               ["read_temp[$lanes{$_}]" => "mask[$_] ? ".
        #                "8'bz : read_data[$lanes{$_}]"]
        #               ),
        #              );
        #     } # for mask-bits
        # } else {
        #     $module->add_contents
        #         (
        #          e_assign->new
        #          (
        #           ["read_temp" => "mask ? 8'bz : read_data"]
        #           ),
        #          );
        # }
        
     # process (clk)
      # begin
        # if clk'event and clk = '1' then
          # first_half_dq <= read_data(31 DOWNTO 16);
          # second_half_dq <= read_data(15 DOWNTO 0);
       # end if;
      # end process;
        
        $module->add_contents
        (
         e_process->new
         ({
             comment => " read data transition from single to double clock rate",
             contents =>
             [
               e_assign->news 
               (
                  ["first_half_dq" => "read_data[".($dq_width*2-1).":".$dq_width."]"],
                  ["second_half_dq" => "read_data[".($dq_width-1).":0]"],
               ),
             ],
         }),
    
             #  dq <= A_WE_StdLogicVector((std_logic'(clk) = '0'), first_half_dq, second_half_dq);
             e_assign->new([read_dq => "clk  ? second_half_dq : first_half_dq"]),
    
             # ddr_dqs <= A_WE_StdLogicVector((std_logic'(dqs_valid) = '1'), A_REP(clk, 2), A_REP(std_logic'('Z'), 2));
             # ddr_dq <= A_WE_StdLogicVector((std_logic'(dq_valid) = '1'), read_dq, A_REP(std_logic'('Z'), 16));
             e_assign->new([dqs_temp   => "dqs_valid ? {".$dqs_width."{clk}} : {".$dqs_width."{1'bz}}"]),
             e_assign->new([dq_temp    => "dq_valid  ? read_dq : {".$dq_width."{1'bz}}"]),
         );

         if ($number_of_lump_delays > 0) {
            $module->add_contents
            (
             # model the effect of cas2.5 as two 90 deg delays
               e_assign->new ({lhs => "dqs_out_0", rhs => "dqs_temp", sim_delay => ($clockperiod / 4), }),
               e_assign->new ({lhs => "dq_out_0",  rhs => "dq_temp",  sim_delay => ($clockperiod / 4), }),
               e_assign->new ({lhs => $dqs, rhs => "dqs_out_0", sim_delay => ($clockperiod / 4), }),
               e_assign->new ({lhs => $dq,  rhs => "dq_out_0",  sim_delay => ($clockperiod / 4), }),
               );
         
         } else  
         {
            $module->add_contents
            (
               e_assign->new ({lhs => $dqs, rhs => "dqs_temp", }),
               e_assign->new ({lhs => $dq,  rhs => "dq_temp", }),
            );
         }

     
    
        
    $module->add_contents
    (        
         e_process->new
         ({
             comment => "Pipelining registers for burst counting",
             contents =>
             [
                e_assign->news 
                (
                    ["write_valid"  => "write_cmd"],
                    ["write_valid_r"  => "write_valid"],
                    ["read_valid_r" => "read_valid"],
                    ["write_valid_r2" => "write_valid_r"],
                    ["write_valid_r3" => "write_valid_r2"],
                    ["write_to_ram_r" => "write_to_ram"],
                    ["read_valid_r2" => "read_valid_r"],
                    ["read_valid_r3" => "read_valid_r2"],
                    ["read_valid_r4" => "read_valid_r3"],
                ),
             ],
         }), 
    );

    if ($local_burst_length == 4) 
    {
        # Memory BL8, local bl4 support
        $module->add_contents
        (        
             e_assign->new(["write_to_ram" => "write_valid || write_valid_r || write_valid_r2 || write_valid_r3"]),
             e_assign->new(["dq_valid" => "read_valid_r || read_valid_r2 || read_valid_r3 || read_valid_r4"]),
         );
    }
    elsif ($local_burst_length == 2) {
        # Memory BL4, local bl2 support
        $module->add_contents
        (
             e_assign->new(["write_to_ram" => "write_valid || write_valid_r"]),
             e_assign->new(["dq_valid" => "read_valid_r || read_valid_r2"]),
         );
    } 
    else { 
        # No burst support
        $module->add_contents
        (        
             e_assign->new(["write_to_ram" => "write_valid"]),
             e_assign->new(["dq_valid" => "read_valid_r"]),
         );
    };
    
    $module->add_contents
    (        
         e_assign->new(["dqs_valid" => "dq_valid || dqs_valid_temp"]),

         e_process->new
         ({
             comment => " ",
             clock_level => "0",
             contents =>
             [
                e_assign->news 
            (
                ["dqs_valid_temp" => "read_valid"],
            ),
             ],
         }), 
         
      # -- rising edge capture 
      # process (ddr_dqs(0))
      # begin
          # -- 
          # if rising_edge(ddr_dqs(0)) then 
            # dq_captured(7 DOWNTO 0) <= ddr_dq(7 DOWNTO 0);
            # dm_captured(0 DOWNTO 0) <= ddr_dm(0 DOWNTO 0);
          # end if;
      # end process;
    
         e_process->new
         ({
             comment => "capture first half of write data with rising edge of DQS, for simulation use only 1 DQS pin",
             clock   => "ddr_dqs[0]",
             contents => 
             [
                e_assign->news
                (
                  ["dq_captured[".($dq_width-1).":0]" => "ddr_dq[".($dq_width-1).":0]"],
                  ["dm_captured[".($dm_width-1).":0]" => "ddr_dm[".($dm_width-1).":0]"],
                ),
             ]
         }),
    
      # -- falling edge capture 
      # process (ddr_dqs(0))
      # begin
          # -- 
          # if falling_edge(ddr_dqs(0)) then 
            # dq_captured(23 DOWNTO 16) <= ddr_dq(7 DOWNTO 0);
            # dm_captured(2 DOWNTO 2) <= ddr_dm(0 DOWNTO 0);
          # end if;
      # end process;
    
         e_process->new
         ({
             comment => "capture second half of write data with falling edge of DQS, for simulation use only 1 DQS pin",
             clock   => "ddr_dqs[0]",
             clock_level => 0,
             contents => 
             [
                e_assign->news
                (
                  ["dq_captured[".($dq_width*2-1).":".($dq_width)."]" => "ddr_dq[".($dq_width-1).":0]"],
                  ["dm_captured[".($dm_width*2-1).":".($dm_width)."]" => "ddr_dm[".($dm_width-1).":0]"],
                ),
             ]
         }),
    

     ); #   end of add_contents() 

         
    $module->add_contents
    (
       # there will always be at least DM[0]
        e_process->new
         ({
             comment => "Support for incomplete writes, do a read-modify-write with mem_bytes and the write data",
             contents => [ 
                e_if->new
                ({
                      condition => "write_to_ram",
                      then => [e_assign->news (["rmw_temp[7:0]","dm_captured[0] ? mem_bytes[7 : 0] : dq_captured[7 : 0]"],),],
                }),
             ],
         }),
    );
    
    # now do the rest of DM pins
    if ($mem_mask_width > 1) {
        for (1 .. ($mem_mask_width-1)) 
        {
            $byte_lane = $_;
            $lanes{$byte_lane} = (($byte_lane*8)+7).":".($byte_lane*8);
            $module->add_contents
            (
                e_process->new
                 ({
                     contents => [ 
                        e_if->new
                        ({
                              condition => "write_to_ram",
                              then => [e_assign->news (["rmw_temp[$lanes{$byte_lane}]" => "dm_captured[$byte_lane] ? "."mem_bytes[$lanes{$byte_lane}] : "."dq_captured[$lanes{$byte_lane}]"],),],
                        }),
                     ],
                 }),
            );
        } # for (0 to ($dm_width-1))
    } 
    $module->add_contents
    (
         e_assign->new(["mem_bytes" => "(rmw_address == wr_addr_delayed) ? rmw_temp : read_data"]),
         e_assign->new(["rmw_address", "(write_to_ram) ? wr_addr_pipe_1 : read_addr_delayed"]),
         e_assign->new(["wr_addr_delayed","wr_addr_pipe_2"]) 
        ); 
        
        $module->add_contents
            (
             e_signal->news
             (
              {name => "read_addr", width => $read_addr_width, never_export => 1},
              {name => "read_valid",width => 1,                never_export => 1},
              ),
    
             e_mux->new
             ({
                 comment=> "use index to select which pipeline stage drives addr",
                 type   => "selecto",
                 selecto=> "index",
                 lhs    => "read_addr_delayed",
                 table  => 
                 [
                      0 => "rd_addr_pipe_0",
                      1 => "rd_addr_pipe_1",
                      2 => "rd_addr_pipe_2",
                      3 => "rd_addr_pipe_3",
                      4 => "rd_addr_pipe_4",
                      5 => "rd_addr_pipe_5",
                 ],
             }),
    
             e_mux->new
             ({
                 comment=> "use index to select which pipeline stage drives valid",
                 type   => "selecto",
                 selecto=> "index",
                 lhs    => "read_valid",
                 table  => 
                     [
                      0 => "rd_valid_pipe[0]",
                      1 => "rd_valid_pipe[1]",
                      2 => "rd_valid_pipe[2]",
                      3 => "rd_valid_pipe[3]",
                      4 => "rd_valid_pipe[4]",
                      5 => "rd_valid_pipe[5]",
                      ],
             }),
             );
             
    
        print "# Finished creating memory model\n";
             
        # Produce some output.
        # print "\&make_sodimm: sim_model_base = $sim_model_base\n";
        # print "\&make_sodimm: about to generate output...\n";
        # $project->_verbose(1);
        $project->output();
    }
} # &make_sodimm

qq{
Do you know how to let the 
mountain stream cleanse your mind?
Every thought is pulled out along the smooth,
polished stones, disappearing
downstream in the frothy current.
The mind keeps on making more thoughts
until it sees that they are 
all being carried away downstream; 
until it realizes that they 
are all vanishing,
dissolving into an unseen point.
Then it won抰 bother for awhile. 
 - Ji Aoi Isshi
};

&make_ddr_sim_model(@ARGV);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -