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

📄 generate_ddr_sim_model.pl

📁 基于NIOS II的ddr2控制器,配有详细的文档,经验证后可使用.
💻 PL
📖 第 1 页 / 共 5 页
字号:
                                                  ),
                                                ],
                                   else      => ["write_cmd" => "1'b0"],
                               }),
                               
                               e_if->new({
                                   comment   => " This is an activate - store the chip/row/bank address in the same order as the DDR controller",
                                   condition => "(cmd_code == 3'b011)",
                                   then      => ["open_rows[current_row]" => "a"],
                               }),
                               
                               e_if->new({
                                   comment   => "Load mode register - set CAS latency, burst mode and length",
                                   condition => "(cmd_code == 3'b000 && ba == 2'b00)",
                                   then      => 
                                    [
                                        e_assign->news
                                            (["burstmode" => "a[3]"],
                                             ["burstlength" => "a[2:0] << 1"],
                                             # ["wr_addr_pipe_0" => "0"], # otherwise if the first write is partial it breaks!
                                            ),
                                    
                                         e_if->new({
                                            comment    => "Decode CAS Latency from bits a[6..4]",
                                            condition  => "(a[6:4] == 3'b011)",
                                            then       => 
                                            [
                                                e_assign->news (["index" => "3'b010" ],)
                                            ],
                                            else       => 
                                            [
                                                 e_if->new({
                                                    comment    => "CAS Latency = 4.0 ",
                                                    condition  => "(a[6:4] == 3'b100)",
                                                    then       => 
                                                    [
                                                        e_assign->news
                                                        (["index" => "3'b011" ],)
                                                    ],
                                                    else =>
                                                    [
                                                        e_assign->news
                                                        (["index" => "3'b100" ],)
                                                    ],
                                                }),                                            
                                                ],
                                         }),
                                     ],   
                                           
                               }),
                               
                               
                               e_assign->news
                               (
                    
                    ["rd_addr_pipe_5"  => "rd_addr_pipe_4"],
                    ["rd_addr_pipe_4"  => "rd_addr_pipe_3"],
                    ["rd_addr_pipe_3"  => "rd_addr_pipe_2"],
                    ["rd_addr_pipe_2"  => "rd_addr_pipe_1"],
                    ["rd_addr_pipe_1"  => "rd_addr_pipe_0"],
    
                    ["rd_valid_pipe[5:1]" => "rd_valid_pipe[4:0]"],
                    ["rd_valid_pipe[0]" => "(cmd_code == 3'b101)"],
                    
                    ["wr_addr_pipe_5"  => "wr_addr_pipe_4"],
                    ["wr_addr_pipe_4"  => "wr_addr_pipe_3"],
                    ["wr_addr_pipe_3"  => "wr_addr_pipe_2"],
                    ["wr_addr_pipe_2"  => "wr_addr_pipe_1"],
                    ["wr_addr_pipe_1"  => "wr_addr_pipe_0"],
    
                    ["wr_valid_pipe[5:1]" => "wr_valid_pipe[4:0]"],
                    ["wr_valid_pipe[0]" => "(cmd_code == 3'b100)"],
                    
                    # ["write_valid_r"  => "write_valid"],
                    # ["write_valid_r2"  => "write_valid_r"],
                    ["wr_addr_delayed_r"  => "wr_addr_delayed"],
                               ),
                               ],
                           }),
                      ],
              }),
             );

       if ($local_burst_length > 1)
       {
           my $burstcounter_size = $local_burst_length / 2; # burst length count need to wrap within a burst length, so we need a suitable sized counter
        
        # Burst support - make the wr_addr keep counting 
        $module->add_contents
            (
             e_process->new
             ({
                 comment => " Burst support - make the wr_addr & rd_addr keep counting",
                 contents => 
                     [
                           e_if->new({ # WRITES
                               comment => " Reset write address otherwise if the first write is partial it breaks!",
                               condition => "(cmd_code == 3'b000 && ba == 2'b00)",
                               then      => 
                               [
                                    e_assign->news ( ["wr_addr_pipe_0" => "0"], 
                                                     ["wr_burst_counter" => "0"], ),
                               ],
                               else => 
                               [
                                    e_if->new({
                                       condition => "(cmd_code == 3'b100)",
                                       then      => 
                                       [
                                           e_assign-> news 
                                           (
                                                 ["wr_addr_pipe_0"   => "{ba,open_rows[current_row],addr_col}"],
                                                 ["wr_burst_counter[".($read_addr_width-1).":".($burstcounter_size)."]" => "{ba,open_rows[current_row],addr_col[".($col_width-2).":".($burstcounter_size)."]}"],
                                                 ["wr_burst_counter[".($burstcounter_size-1).":0]" => "addr_col[".($burstcounter_size-1).":0] + 1"],
                                           ),
                                       ],
                                       else => 
                                       [
                                           e_if->new({
                                               # condition => "(write_cmd == 1'b1) || (write_to_ram == 1'b1)",
                                               condition => "(write_cmd || write_to_ram)",
                                               then      => 
                                               [
                                                   # e_assign-> news (["wr_addr_pipe_0" => "{ba,open_rows[current_row],addr_col}"],),
                                                   e_assign-> news (["wr_addr_pipe_0" => "wr_burst_counter"],),
                                                   e_assign-> news (["wr_burst_counter[".($burstcounter_size-1).":0]" => "wr_burst_counter[".($burstcounter_size-1).":0] + 1"],),
                                               ],
                                               else      => 
                                               [
                                                    e_assign-> news (["wr_addr_pipe_0" => "0"],),
                                               ],
                                           }),
                                       
                                       ],
                                   }),
                                       
                               ],
                        }),

                           e_if->new({  # READS
                               comment => " Reset read address otherwise if the first write is partial it breaks!",
                               condition => "(cmd_code == 3'b000 && ba == 2'b00)",
                               then      => 
                               [
                                    e_assign->news ( ["rd_addr_pipe_0" => "0"], ),
                               ],
                               else => 
                               [
                                    e_if->new({
                                       condition => "(cmd_code == 3'b101)",
                                       then      => 
                                       [
                                           e_assign-> news 
                                           (
                                                 ["rd_addr_pipe_0"   => "{ba,open_rows[current_row],addr_col}"],
                                                 ["rd_burst_counter[".($read_addr_width-1).":".($burstcounter_size)."]" => "{ba,open_rows[current_row],addr_col[".($col_width-2).":".($burstcounter_size)."]}"],
                                                 ["rd_burst_counter[".($burstcounter_size-1).":0]" => "addr_col[".($burstcounter_size-1).":0] + 1"],
                                           ),
                                       ],
                                       else => 
                                       [
                                           e_if->new({
                                               condition => "(read_cmd || dq_valid || read_valid)",
                                               then      => 
                                               [
                                                   e_assign-> news (["rd_addr_pipe_0" => "rd_burst_counter"],),
                                                   e_assign-> news (["rd_burst_counter[".($burstcounter_size-1).":0]" => "rd_burst_counter[".($burstcounter_size-1).":0] + 1"],),
                                               ],
                                               else      => 
                                               [
                                                    e_assign-> news (["rd_addr_pipe_0" => "0"],),
                                               ],
                                           }),
                                       
                                       ],
                                   }),
                                       
                               ],
                           }), # end of READS
                        
                       ], # end of contents
                 }),
             );
       } 
       else {
            
        $module->add_contents # no Burst support
           (
             e_process->new
             ({
                 contents => 
                 [
                       e_if->new({
                           comment => " Reset write address otherwise if the first write is partial it breaks!",
                           condition => "(cmd_code == 3'b000 && ba == 2'b00)",
                           then      => 
                           [
                                e_assign->news ( ["wr_addr_pipe_0" => "0"],), 
                           ],
                           else => 
                           [
                                e_if->new({
                                   condition => "(cmd_code == 3'b100)",
                                   then      => 
                                   [
                                       e_assign-> news 
                                       (
                                             ["wr_addr_pipe_0"   => "{ba,open_rows[current_row],addr_col}"],
                                       ),
                                   ],
                               }),
                                   
                             ],
                        }),
                        e_if->new({
                           comment => "Read request so store the read address",
                           condition => "(cmd_code == 3'b101)",
                           then      => 
                           [
                               e_assign-> news 
                               (
                                     ["rd_addr_pipe_0"   => "{ba,open_rows[current_row],addr_col}"],
                               ),
                           ],
                       }),
                       
                               
                   ],
              }),
           );           
       } # 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  => "dqs_valid ? {".$dqs_width."{clk}} : {".$dqs_width."{1'bz}}"]),
           #e_assign->new([$dq   => "dq_valid  ? read_dq : {".$dq_width."{1'bz}}"]),
         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}}"]),

         # model the board trace delay
           e_assign->new
           ({

⌨️ 快捷键说明

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