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

📄 generate_ddr_sim_model.pl

📁 基于NIOS II的ddr2控制器,配有详细的文档,经验证后可使用.
💻 PL
📖 第 1 页 / 共 5 页
字号:
               lhs => $dqs,
               rhs => "dqs_temp",
               sim_delay => $rtl_board_delay,
           }),
           e_assign->new
           ({ 
               lhs => $dq,
               rhs => "dq_temp",
               sim_delay => $rtl_board_delay,
           }),

         );

    $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_process->new
         # ({
             # comment => " ",
             # contents =>
             # [
                # e_assign->news 
            # (
                # ["dq_valid" => "read_valid"],
            # ),
             # ],
         # }), 
    
         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   => $default_pin_prefix."dqs[0]",
             contents => 
             [
                e_assign->news
                (
                  ["dq_captured[".($dq_width-1).":0]" => $default_pin_prefix."dq[".($dq_width-1).":0]"],
                  ["dm_captured[".($dm_width-1).":0]" => $default_pin_prefix."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   => $default_pin_prefix."dqs[0]",
             clock_level => 0,
             contents => 
             [
                e_assign->news
                (
                  ["dq_captured[".($dq_width*2-1).":".($dq_width)."]" => $default_pin_prefix."dq[".($dq_width-1).":0]"],
                  ["dm_captured[".($dm_width*2-1).":".($dm_width)."]" => $default_pin_prefix."dm[".($dm_width-1).":0]"],
                ),
             ]
         }),
    
     );

         
    $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_valid",
                      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_valid",
                              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))
    } # if dm_width > 1
    
    # ["rmw_temp[15:8]","dm_captured[1] ? mem_bytes[15 : 8]   : dq_captured[15 : 8]"],
    # ["rmw_temp[23:16]","dm_captured[2] ? mem_bytes[23 : 16]   : dq_captured[23 : 16]"],
    # ["rmw_temp[31:24]","dm_captured[3] ? mem_bytes[31 : 24]   : dq_captured[31 : 24]"],

    $module->add_contents
    (
         # e_assign->new(["mem_bytes" => "(rmw_address == wr_addr_delayed) ? rmw_temp : read_data"]),
         e_assign->new(["mem_bytes" => "(rmw_address == wr_addr_delayed_r) ? rmw_temp : read_data"]),
         # e_assign->new(["rmw_address", "(write_valid) ? wr_addr_delayed : read_addr_delayed"]),
         e_assign->new(["rmw_address", "(write_to_ram) ? wr_addr_delayed : read_addr_delayed"]),

         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]",
                      ],
             }),
    
             e_mux->new
             ({
                 comment=> "DDR2 has variable write latency too, so use index to select which pipeline stage drives valid",
                 type   => "selecto",
                 selecto=> "index",
                 lhs    => "write_valid",
                 table  => 
                     [
                      0 => "wr_valid_pipe[0]",
                      1 => "wr_valid_pipe[1]",
                      2 => "wr_valid_pipe[2]",
                      3 => "wr_valid_pipe[3]",
                      4 => "wr_valid_pipe[4]",
                      5 => "wr_valid_pipe[5]",
                      ],
             }),
             e_mux->new
             ({
                 comment=> "DDR2 has variable write latency too, so use index to select which pipeline stage drives addr",
                 type   => "selecto",
                 selecto=> "index",
                 lhs    => "wr_addr_delayed",
                 table  => 
                 [
                      0 => "wr_addr_pipe_0",
                      1 => "wr_addr_pipe_1",
                      2 => "wr_addr_pipe_2",
                      3 => "wr_addr_pipe_3",
                      4 => "wr_addr_pipe_4",
                      5 => "wr_addr_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();
    } else {
        print "# Skipping creation of memory model because do_generation = $do_generation\n";
        
    }
    
} # &make_sodimm

&make_ddr_sim_model(@ARGV);

⌨️ 快捷键说明

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