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

📄 generate_ddr_sim_model.pl

📁 基于NIOS II的ddr2控制器,配有详细的文档,经验证后可使用.
💻 PL
📖 第 1 页 / 共 4 页
字号:
             e_signal->news
             (
              {name => "rd_valid_pipe",   width=> 6}, # was 5?
              {name => "latency",         width=> 3},
              {name => "index",           width=> 3},
              ),
             );
        
        ## Set up ram read/wr var's and initial block to readmem our dat file:
        $module->add_contents
            (
             e_signal->news
             (
              {name => "rmw_temp", width=> $mem_width},
              {name => "mem_bytes",width=> $mem_width},
              {name => "read_data",width=> $mem_width},
              {name => "read_temp",width=> $mem_width,export => 0, never_export => 1},
              {name => "read_valid",width=> 1,export => 0, never_export => 1},
              {name => "read_cmd",width=> 1,export => 0, never_export => 1},
              {name => "write_valid_r" , width => 1, export => 0, never_export => 1},
              {name => "read_valid_r"  , width => 1, export => 0, never_export => 1},
              {name => "write_valid_r2", width => 1, export => 0, never_export => 1},
              {name => "write_valid_r3", width => 1, export => 0, never_export => 1},
              {name => "write_to_ram_r", width => 1, export => 0, never_export => 1},
              {name => "read_valid_r2" , width => 1, export => 0, never_export => 1},
              {name => "read_valid_r3" , width => 1, export => 0, never_export => 1},
              {name => "read_valid_r4" , width => 1, export => 0, never_export => 1},             
          
              {name => "cas2",width=> 1,export => 0, never_export => 1},
              {name => "cas25",width=> 1,export => 0, never_export => 1},
              {name => "cas3",width=> 1,export => 0, never_export => 1},
              {name => "burstmode",width=> 1,export => 0, never_export => 1},
              {name => "burstlength",width=> 3,export => 0, never_export => 1},
              ),
             e_assign->new(["current_row" => "{cs_n,ba}"]),
             );
    
        #sjh - No need for *read* masking with DDR
        # # Try to make life easier by defining the necessary number of byte lane
        # #field descriptors like 7:0, 15:8, etc...
        my %lanes;
        my $byte_lane;
        # # assign rmw_temp[7:0]= dqm[0] ? mem_bytes[7:0] : $dq[7:0]
        # if ($mem_mask_width > 1) {
            # for (0 .. ($mem_mask_width-1))
            # {
                # $byte_lane = $_;
                # $lanes{$byte_lane} = (($byte_lane*8)+7).":".($byte_lane*8);
                # $module->add_contents
                    # (
                     # e_assign->new
                     # (
                      # ["rmw_temp[$lanes{$byte_lane}]" =>
                       # "dm[$byte_lane] ? ".
                       # "mem_bytes[$lanes{$byte_lane}] : ".$dq."[$lanes{$byte_lane}]"]
                      # )
                     # );
            # } # for (0 to ($dm_width-1))
        # } else {
            # $module->add_contents
                # (
                 # e_assign->new(["rmw_temp" => "dm ? mem_bytes : ".$dq])
                 # );
        # }
        
        # Build the Main Process:
        $module->add_contents
            (
             e_process->new
             ({
                 comment => " Decode commands into their actions",
                 contents => 
                     [
                      e_if->new({
                          comment => " No Activity if the clock is",
                          condition => "cke",
                          then => 
                              [
                              e_if->new({
                                   comment   => " This is a read command",
                                   condition => "(cmd_code == 3'b101)",
                                   then      => [e_assign->news 
                                                 (["read_cmd" => "1'b1"],
                                                  #["rd_addr_pipe_0" => "{ba,open_rows[current_row],addr_col}"],
                                                 ),
                                                ],
                                   else      => ["read_cmd"  => "1'b0"],
                               }),
                               
                               e_if->new({
                                   comment   => " This is a write command",
                                   condition => "(cmd_code == 3'b100)",
                                   then      => [e_assign-> news
                                                 (["write_cmd" => "1'b1"],
                                                  #["wr_addr_pipe_0" => "{ba,open_rows[current_row],addr_col}"],
                                                  ),
                                                ],
                                   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'b010)",
                                            then       => 
                                            [
                                                e_assign->news
                                                (["cas2" => "1'b1"],
                                                 ["index" => "3'b001" ],)
                                            ],
                                            else       => 
                                            [
                                                 e_if->new({
                                                    comment    => "CAS Latency = 2.5 ",
                                                    condition  => "(a[6:4] == 3'b110)",
                                                    then       => 
                                                    [
                                                        e_assign->news
                                                        (["cas25" => "1'b1"],
                                                         ["index" => "3'b001" ],)
                                                    ],
                                                    else =>
                                                    [
                                                        e_assign->news
                                                        (["cas3" => "1'b1"],
                                                         ["index" => "3'b010" ],)
                                                    ],
                                                }),                                            
                                                ],
                                         }),
                                     ],   
                                           
                               }),
                               
                               
                               e_assign->news
                               (
                                    ["rd_valid_pipe[5:1]" => "rd_valid_pipe[4:0]"],
                                    
                                    ["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[0]" => "(cmd_code == 3'b101)"],
                                    
                                    ["wr_addr_pipe_3"  => "wr_addr_pipe_2"],
                                    ["wr_addr_pipe_2"  => "wr_addr_pipe_1"],
                                    ["wr_addr_pipe_1"  => "wr_addr_pipe_0"],
                    
                               ),
                               ],
                           }),
                      ],
              }),
             );

       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}"],
                               ),
                           ],
                       }),
                       
                               

⌨️ 快捷键说明

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