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

📄 em_de2_pio.pl

📁 DE2_PIO Controller For Altera SOPC Builder and NIOS on DE2 kit board
💻 PL
📖 第 1 页 / 共 2 页
字号:
                        type    => "integer",                        default => 0,                       });  # Test to make sure the reset-value fits:  $Options->{reset_value_bits} = &Bits_To_Encode($Options->{reset_value});  &validate_parameter ({hash    => $Options,                        name    => "reset_value_bits",                        range   => [0, $Options->{width}],                       });  # Build-up some derived "Option" values, which are handy to   # have as booleans:  $Options->{has_any_input}  = $Options->{has_tri} || $Options->{has_in};  $Options->{has_any_output} = $Options->{has_tri} || $Options->{has_out};  # If we've specified an IRQ, there must be some kind of input.  # Likewise for edge-detection.  $Options->{has_edge}       = $Options->{edge_type} ne "NONE";  $Options->{irq_on_edge}    = $Options->{irq_type}  eq "EDGE";  &validate_parameter ({hash         => $Options,                        name         => "has_irq",                        optional     => 1,                        requires     => "has_any_input",                       });  &validate_parameter ({hash         => $Options,                        name         => "has_edge",                        optional     => 1,                        requires     => "has_any_input",                       });  &validate_parameter ({hash         => $Options,                        name         => "irq_on_edge",                        optional     => 1,                        requires     => "has_edge",                       });#    warn "done with options\n";#    foreach my $key (keys (%$Options))#    {#       warn "  $key gets $Options->{$key}\n";#    }}################################################################# make_pio## Given a name and a hashful of options, builds an e_module object# which implements a PIO peripheral.#################################################################sub make_pio{  my ($module, $Opt) = (@_);  &Validate_PIO_Options ($Opt);  # Create a new, empty module, and mark it as the one into which  # all new "things" should go.  It gets unmarked when this subroutine  # exits and "$marker" is destroyed.  #  my $marker = e_default_module_marker->new($module);  # Leo is silly about hating the range [0:0] applied to scalars.  # To get around this, we precompute the bit-ragen appropriate for   # this PIO -as a string-, which may be null ("") for a 1-bit PIO.  #  my $bitrange = ($Opt->{width} > 1)? '[' . ($Opt->{width} - 1) . ':0]' : "";  e_signal->adds (                  [edge_capture_wr_strobe => 1],                  [clk_en => 1,0,1],                  [chipselect => 1],                  [clk => 1],                  [reset_n => 1],                  );  # We don't really use the global clock-enable in this peripheral:  e_assign->add (["clk_en", 1]);  ################  # First, declare my PIO port signals:  #  e_port->add(["bidir_port", $Opt->{width}, "inout"]) if $Opt->{has_tri};  e_port->add(["in_port",    $Opt->{width}, "in"   ]) if $Opt->{has_in};  e_port->add(["out_port",   $Opt->{width}, "out"  ]) if $Opt->{has_out};  ################  # Addressable-register infrastructure:  #    Read-mux             (starts off blank--sometimes doesn't exist)  #    readdata-register    (also sometimes doesn't exist)  #    avalon-slave port    (always exists)  #    read/writedata ports (sometimes don't exist)  #  e_avalon_slave->add ({name => "s1",});  # I want my slave-ports seen by the SOPC-Builder.  e_port->add(["address", 2, "in"]);  if ($Opt->{has_any_output} || $Opt->{has_irq} || $Opt->{has_edge}) {    e_port->adds(["writedata", $Opt->{width}, "in"],                 ["write_n"  ,            1 , "in"]);  }  my $read_mux;  if ($Opt->{has_any_input})   {    e_port->add(["readdata",  $Opt->{width}, "output"]);    $read_mux = e_mux->add ({lhs  => e_signal->add (["read_mux_out",                                                     $Opt->{width}  ]),                             type => "and-or",                             });    # Note that the register on "readdata" implies one-wait-state access.    e_register->add ({out => "readdata",                      in  => "read_mux_out"});  }  ################  # Writeable data-out register, if reqired.  #  if ($Opt->{has_any_output}) {    e_register->add       ({out         => e_signal->add (["data_out", $Opt->{width}]),        in          => "writedata $bitrange",        enable      => "chipselect && ~write_n && (address == 0)",        async_value => $Opt->{reset_value},       });    # While we're here, do the actual output-assignment:    if ($Opt->{has_tri}) {      # Lovingly-assign each bit depending on direction-register.      # Deal with Leo's hatred of bit-selects on scalar wires:      if ($Opt->{width} == 1) {        e_assign->add (["bidir_port", "data_dir ? data_out : 1'bZ"]);      } else {        for (my $i = 0; $i < $Opt->{width}; $i++) {          e_assign->add (["bidir_port[$i]",                           "data_dir[$i] ? data_out[$i] : 1'bZ"]);        }      }    }    e_assign->add (["out_port", "data_out"]) if $Opt->{has_out};  }  ################   # Readable data-in register, if required.  #   if ($Opt->{has_any_input}) {    e_signal->add(["data_in", $Opt->{width}]);    e_assign->add(["data_in", "in_port"   ]) if $Opt->{has_in};    e_assign->add(["data_in", "bidir_port"]) if $Opt->{has_tri};    $read_mux->add_table ("(address == 0)" => "data_in");  }  ################  # Writeable / Readable data-direction register, if required.  #  if ($Opt->{has_tri}) {    e_register->add ({out    => e_signal->add (["data_dir", $Opt->{width}]),                      in     => "writedata $bitrange",                      enable => "chipselect && ~write_n && (address == 1)",                     });    $read_mux->add_table ("(address == 1)" => "data_dir");  }  ################  # Writeable/readable interrupt-masking register, if required.  #  if ($Opt->{has_irq}) {    e_register->add ({out    => e_signal->add (["irq_mask", $Opt->{width}]),                      in     => "writedata $bitrange",                      enable => "chipselect && ~write_n && (address == 2)",                     });    $read_mux->add_table ("(address == 2)" => "irq_mask");    e_port->add(["irq" => 1, "output"]);    ##########    # While we're in here, compute the IRQ-result:    if      ($Opt->{irq_type} eq "LEVEL") {      e_assign->add (["irq", "|(data_in      & irq_mask)"])     } elsif ($Opt->{irq_type} eq "EDGE") {      e_assign->add (["irq", "|(edge_capture & irq_mask)"])     } else {      &ribbit ("Unexpected bad irq_type: $Opt->{irq_type}");    }  }  ################  # Readable / clearable edge-capture register.  # Each bit of this register is set by an edge on the corresponding   # input-bit, and all   #  if ($Opt->{has_edge}) {    e_signal->add (["edge_capture", $Opt->{width}]);    $read_mux->add_table ("(address == 3)" => "edge_capture");    e_assign->add ([                    "edge_capture_wr_strobe",                    "chipselect && ~write_n && (address == 3)",                    ]);    # Create S/R registers for each bit, MSB-first (so list is in right order)    # Deal with Leo's hatred of bit-selects on scalar wires:    if ($Opt->{width} == 1) {        e_register->add ({out        => "edge_capture",                          sync_set   => "edge_detect",                          sync_reset => "edge_capture_wr_strobe",                         });    } else {      for (my $i = 0; $i < $Opt->{width}; $i++) {        e_register->add ({out        => "edge_capture[$i]",                          sync_set   => "edge_detect[$i]",                          sync_reset => "edge_capture_wr_strobe",                         });      }    }    ################    # Edge-detection mechanism    #    # Synchronize incoming data-signals (this bit us in both the     #   1.0 and 1.1 releases).      e_register->add({in => "data_in", delay => 2});    e_signal->add (["edge_detect", $Opt->{width}]);    if ($Opt->{edge_type}      eq "RISING") {      e_assign->add (["edge_detect", " d1_data_in & ~d2_data_in"]);    } elsif ($Opt->{edge_type} eq "FALLING") {      e_assign->add (["edge_detect", "~d1_data_in & d2_data_in"]);    } elsif ($Opt->{edge_type} eq "ANY") {      e_assign->add (["edge_detect", " d1_data_in ^  d2_data_in"]);    } else {      &ribbit ("Unexpected bad edge type: $Opt->{edge_type}");    }  }  return $module;}

⌨️ 快捷键说明

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