replace PartitionedSignal with SimdSignal master
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 10 Oct 2021 12:26:49 +0000 (13:26 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 10 Oct 2021 12:27:26 +0000 (13:27 +0100)
48 files changed:
flake.lock [new file with mode: 0644]
flake.nix [new file with mode: 0644]
nix/bigfloat.nix [new file with mode: 0644]
nix/c4m-jtag.nix [new file with mode: 0644]
nix/ecp5-program.nix [new file with mode: 0644]
nix/ecp5.nix [new file with mode: 0644]
nix/ieee754fpu.nix [new file with mode: 0644]
nix/litex.toml [new file with mode: 0644]
nix/ls180.nix [new file with mode: 0644]
nix/modgrammar.nix [new file with mode: 0644]
nix/nmutil.nix [new file with mode: 0644]
nix/openpower-isa.nix [new file with mode: 0644]
nix/pinmux.nix [new file with mode: 0644]
nix/soc.nix [new file with mode: 0644]
nix/verilog.nix [new file with mode: 0644]
pinmux
src/soc/config/pinouts.py
src/soc/config/test/test_pi2ls.py
src/soc/experiment/compldst_multi.py
src/soc/experiment/pi2ls.py
src/soc/experiment/pimem.py
src/soc/experiment/test/pagetables.py [new file with mode: 0644]
src/soc/experiment/test/test_compldst_multi_mmu.py
src/soc/experiment/test/test_dcbz_pi.py
src/soc/experiment/test/test_l0_cache_buffer2.py
src/soc/experiment/test/test_mmu_dcache_pi.py
src/soc/experiment/test/test_wishbone.py [new file with mode: 0644]
src/soc/fu/alu/main_stage.py
src/soc/fu/alu/output_stage.py
src/soc/fu/common_output_stage.py
src/soc/fu/compunits/test/test_compunit.py
src/soc/fu/div/core_stages.py
src/soc/fu/div/output_stage.py
src/soc/fu/div/setup_stage.py
src/soc/fu/ldst/loadstore.py
src/soc/fu/logical/main_stage.py
src/soc/fu/logical/output_stage.py
src/soc/fu/mul/main_stage.py
src/soc/fu/mul/post_stage.py
src/soc/fu/mul/pre_stage.py
src/soc/fu/mul/test/helper.py
src/soc/fu/shift_rot/main_stage.py
src/soc/litex/florent
src/soc/simple/test/test_core.py
src/soc/simple/test/test_issuer.py
src/soc/simple/test/test_microwatt.py
src/soc/simple/test/test_runner.py
src/soc/simple/test/teststate.py

diff --git a/flake.lock b/flake.lock
new file mode 100644 (file)
index 0000000..8193dbc
--- /dev/null
@@ -0,0 +1,131 @@
+{
+  "nodes": {
+    "c4m-jtag": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1619101523,
+        "narHash": "sha256-y1OY8URcE1lnu5L7IDFcJ8zT8sqlrfMP9VPNmVvACGk=",
+        "ref": "master",
+        "rev": "c2bf4810f9f91ced7fcda777b92b86ab353da288",
+        "revCount": 146,
+        "type": "git",
+        "url": "https://git.libre-soc.org/git/c4m-jtag.git"
+      },
+      "original": {
+        "type": "git",
+        "url": "https://git.libre-soc.org/git/c4m-jtag.git"
+      }
+    },
+    "migen": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1631614362,
+        "narHash": "sha256-BgYf4e7O/rbS5P1ZpDlcgCEUh2h2vK3FyHADdzyaMg0=",
+        "owner": "m-labs",
+        "repo": "migen",
+        "rev": "7bc4eb1387b39159a74c1dbd1b820728e0bfbbaa",
+        "type": "github"
+      },
+      "original": {
+        "owner": "m-labs",
+        "repo": "migen",
+        "type": "github"
+      }
+    },
+    "nix-litex": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1632150297,
+        "narHash": "sha256-ghlAJBZxLVkQB+9tXEOBOF1FfdT5Pn4292khF4iKCNA=",
+        "ref": "main",
+        "rev": "5ab6984eb1efad0c91d808c9b7b79e00e50ccc05",
+        "revCount": 31,
+        "type": "git",
+        "url": "https://git.sr.ht/~lschuermann/nix-litex"
+      },
+      "original": {
+        "ref": "main",
+        "type": "git",
+        "url": "https://git.sr.ht/~lschuermann/nix-litex"
+      }
+    },
+    "nixpkgs": {
+      "locked": {
+        "lastModified": 1631723418,
+        "narHash": "sha256-Sbey1S81fXUKcEHVCMwlXMju/IoCQxMwP1PPkVYpGrc=",
+        "owner": "L-as",
+        "repo": "nixpkgs",
+        "rev": "8bfc1026477692b933df6eeec27bd494cac3e436",
+        "type": "github"
+      },
+      "original": {
+        "owner": "L-as",
+        "ref": "libresoc",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "nmigen": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1618220900,
+        "narHash": "sha256-Ol2SMZLUTikZWDLmK7F5lZuKBfGO71WmisATPNMTpHQ=",
+        "ref": "master",
+        "rev": "d824795c2c7cb43dcbc8ed8fac6d309d77284913",
+        "revCount": 1056,
+        "type": "git",
+        "url": "https://git.libre-soc.org/git/nmigen.git"
+      },
+      "original": {
+        "type": "git",
+        "url": "https://git.libre-soc.org/git/nmigen.git"
+      }
+    },
+    "nmigen-soc": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1601572554,
+        "narHash": "sha256-v9SH+KuIPydXCr363RUsMg9/tabuu+GjKPJOKq2Jze0=",
+        "ref": "master",
+        "rev": "692017c7eaf21ff37302790c4422db6bd08667be",
+        "revCount": 48,
+        "type": "git",
+        "url": "https://git.libre-soc.org/git/nmigen-soc.git"
+      },
+      "original": {
+        "type": "git",
+        "url": "https://git.libre-soc.org/git/nmigen-soc.git"
+      }
+    },
+    "root": {
+      "inputs": {
+        "c4m-jtag": "c4m-jtag",
+        "migen": "migen",
+        "nix-litex": "nix-litex",
+        "nixpkgs": "nixpkgs",
+        "nmigen": "nmigen",
+        "nmigen-soc": "nmigen-soc",
+        "yosys": "yosys"
+      }
+    },
+    "yosys": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1617979565,
+        "narHash": "sha256-M8ppe+lL/pgd2sXh7bM6/sbk1099KKECeWA5mXtqE6Y=",
+        "owner": "YosysHQ",
+        "repo": "yosys",
+        "rev": "a58571d0fe8971cb7d3a619a31b2c21be6d75bac",
+        "type": "github"
+      },
+      "original": {
+        "owner": "YosysHQ",
+        "repo": "yosys",
+        "rev": "a58571d0fe8971cb7d3a619a31b2c21be6d75bac",
+        "type": "github"
+      }
+    }
+  },
+  "root": "root",
+  "version": 7
+}
diff --git a/flake.nix b/flake.nix
new file mode 100644 (file)
index 0000000..90a976c
--- /dev/null
+++ b/flake.nix
@@ -0,0 +1,98 @@
+{
+  description = "FOSS CPU/GPU/VPU/SoC all in one, see https://libre-soc.org/";
+
+  inputs.nixpkgs.url = "github:L-as/nixpkgs?ref=libresoc"; # for alliance and migen
+  inputs.c4m-jtag.url = "git+https://git.libre-soc.org/git/c4m-jtag.git";
+  inputs.c4m-jtag.flake = false;
+  inputs.nmigen.url = "git+https://git.libre-soc.org/git/nmigen.git";
+  inputs.nmigen.flake = false;
+  inputs.nmigen-soc.url = "git+https://git.libre-soc.org/git/nmigen-soc.git";
+  inputs.nmigen-soc.flake = false;
+  inputs.migen.url = "github:m-labs/migen";
+  inputs.migen.flake = false;
+  inputs.yosys.url = "github:YosysHQ/yosys?rev=a58571d0fe8971cb7d3a619a31b2c21be6d75bac";
+  inputs.yosys.flake = false;
+  # submodules needed
+  inputs.nix-litex.url = "git+https://git.sr.ht/~lschuermann/nix-litex?ref=main";
+  inputs.nix-litex.flake = false;
+
+  outputs = { self, nixpkgs, c4m-jtag, nmigen, nmigen-soc, nix-litex, migen, yosys }:
+    let
+      getv = x: builtins.substring 0 8 x.lastModifiedDate;
+
+      supportedSystems = [ "x86_64-linux" "x86_64-darwin" "aarch64-linux" "aarch64-darwin" ];
+
+      forAllSystems = nixpkgs.lib.genAttrs supportedSystems;
+
+      litex = pkgs: import "${nix-litex}/pkgs" {
+        inherit pkgs;
+        pkgMetas = builtins.fromTOML (builtins.readFile ./nix/litex.toml);
+        skipChecks = true; # FIXME: remove once checks work
+      };
+
+      nixpkgsFor = forAllSystems (system: import nixpkgs { inherit system; overlays = [ self.overlay ]; });
+
+      lib = nixpkgs.lib;
+    in
+    {
+      overlay = final: prev: {
+        python37 = prev.python37.override {
+          packageOverrides = lib.composeExtensions (litex final).pythonOverlay (pfinal: pprev: {
+            libresoc-ieee754fpu = pfinal.callPackage ./nix/ieee754fpu.nix {};
+            libresoc-openpower-isa = pfinal.callPackage ./nix/openpower-isa.nix {};
+            c4m-jtag = pfinal.callPackage (import ./nix/c4m-jtag.nix { src = c4m-jtag; version = getv c4m-jtag; }) {};
+            bigfloat = pfinal.callPackage ./nix/bigfloat.nix {};
+            modgrammar = pfinal.callPackage ./nix/modgrammar.nix {};
+            libresoc-nmutil = pfinal.callPackage ./nix/nmutil.nix {};
+            libresoc-soc = pfinal.callPackage (import ./nix/soc.nix { version = getv self; }) {};
+
+            nmigen-soc = pprev.nmigen-soc.overrideAttrs (_: {
+              doCheck = false;
+              src = nmigen-soc;
+              setuptoolsCheckPhase = "true";
+            });
+
+            nmigen = pprev.nmigen.overrideAttrs (_: {
+              src = nmigen;
+            });
+
+            migen = pprev.migen.overrideAttrs (_: {
+              src = migen;
+            });
+          });
+        };
+
+        yosys = prev.yosys.overrideAttrs (_: {
+          version = "0.9+4052";
+          src = yosys;
+        });
+
+        libresoc-verilog = final.callPackage (import ./nix/verilog.nix { version = getv self; }) { python3Packages = final.python37Packages; };
+        libresoc-ls180 = final.callPackage (import ./nix/ls180.nix { version = getv self; }) { python3Packages = final.python37Packages; };
+        libresoc-ecp5 = final.callPackage (import ./nix/ecp5.nix { version = getv self; }) { python3Packages = final.python37Packages; };
+        libresoc-ecp5-program = final.callPackage (import ./nix/ecp5-program.nix { version = getv self; }) { python3Packages = final.python37Packages; };
+        libresoc-pinmux = final.callPackage (import ./nix/pinmux.nix { version = getv self; }) {};
+      };
+
+      apps = forAllSystems (system: {
+        ecp5 = {
+          type = "app";
+          program = "${nixpkgsFor.${system}.libresoc-ecp5-program}";
+        };
+      });
+      defaultApp = forAllSystems (system: self.apps.${system}.ecp5);
+
+      packages = forAllSystems (system: {
+        soc = nixpkgsFor.${system}.python37Packages.libresoc-soc;
+        verilog = nixpkgsFor.${system}.libresoc-verilog;
+        pinmux = nixpkgsFor.${system}.libresoc-pinmux;
+        ls180 = nixpkgsFor.${system}.libresoc-ls180;
+        ecp5 = nixpkgsFor.${system}.libresoc-ecp5;
+        ecp5-program = nixpkgsFor.${system}.libresoc-ecp5-program;
+        openpower-isa = nixpkgsFor.${system}.python37Packages.libresoc-openpower-isa;
+        debugNixpkgs = nixpkgsFor.${system};
+      });
+
+      defaultPackage = forAllSystems (system: self.packages.${system}.verilog);
+    };
+}
diff --git a/nix/bigfloat.nix b/nix/bigfloat.nix
new file mode 100644 (file)
index 0000000..4355ef0
--- /dev/null
@@ -0,0 +1,21 @@
+{ lib, buildPythonPackage, fetchPypi, gmp, mpfr, six }:
+
+buildPythonPackage rec {
+  pname = "bigfloat";
+  version = "0.4.0";
+
+  buildInputs = [ gmp mpfr ];
+  propagatedBuildInputs = [ six ];
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "WLlr3ocqylmJ0T2C66Os8qoblOIhF91yoWulkRsMDLg=";
+  };
+
+  doCheck = false;
+
+  meta = with lib; {
+    homepage = "https://pypi.org/project/bigfloat/";
+    license = licenses.lgpl3Plus;
+  };
+}
diff --git a/nix/c4m-jtag.nix b/nix/c4m-jtag.nix
new file mode 100644 (file)
index 0000000..cf301c6
--- /dev/null
@@ -0,0 +1,24 @@
+{ version, src }:
+
+{ lib, python, buildPythonPackage, nmigen-soc, nmigen, modgrammar, setuptools-scm }:
+
+buildPythonPackage {
+  pname = "c4m-jtag";
+  inherit src version;
+
+  nativeBuildInputs = [ setuptools-scm ];
+  propagatedBuildInputs = [ nmigen-soc nmigen modgrammar ];
+
+  doCheck = false;
+
+  pythonImportsCheck = [ "c4m.nmigen.jtag.tap" ];
+
+  prePatch = ''
+    export SETUPTOOLS_SCM_PRETEND_VERSION=${version}
+  '';
+
+  meta = with lib; {
+    homepage = "https://pypi.org/project/libresoc-openpower-isa/";
+    license = licenses.lgpl3Plus;
+  };
+}
diff --git a/nix/ecp5-program.nix b/nix/ecp5-program.nix
new file mode 100644 (file)
index 0000000..4d696b2
--- /dev/null
@@ -0,0 +1,24 @@
+{ version }:
+
+{ writeShellScript, openocd, python3Packages, libresoc-ecp5, nextpnr, trellis }:
+
+let
+  pythonWithEnv = python3Packages.python.withPackages (ps: with ps; [
+    requests migen libresoc-soc litex-boards litex litedram liteeth liteiclink litescope litesdcard
+  ]);
+in
+writeShellScript "program-ecp5-libresoc" ''
+  export PATH="${openocd}/bin:${pythonWithEnv}/bin:${trellis}/bin:${nextpnr}/bin:$PATH"
+
+  dir="$(mktemp -d)"
+  pushd "$dir"
+  echo "$dir"
+
+  export PYTHONPATH="${../src/soc/litex/florent}:$PYTHONPATH"
+
+  python ${../src/soc/litex/florent/versa_ecp5.py} --sys-clk-freq=55e6 --load-from ${libresoc-ecp5}
+
+  popd
+  rm -rf "$dir"
+  exit 0
+''
diff --git a/nix/ecp5.nix b/nix/ecp5.nix
new file mode 100644 (file)
index 0000000..1c82ee4
--- /dev/null
@@ -0,0 +1,40 @@
+{ version }:
+
+{ stdenv, python3Packages, yosys, libresoc-verilog, libresoc-pinmux, pkgsCross
+, nextpnr, trellis }:
+
+stdenv.mkDerivation {
+  pname = "libresoc-versa-ecp5.v";
+  inherit version;
+
+  src = ../src/soc/litex/florent;
+
+  nativeBuildInputs =
+    (with python3Packages; [
+    python libresoc-soc litex-boards litex litedram liteeth liteiclink litescope litesdcard
+    ])
+    ++ [ trellis nextpnr pkgsCross.powernv.buildPackages.gcc ];
+
+  postPatch = ''
+    patchShebangs --build .
+  '';
+
+  configurePhase = "true";
+
+  buildPhase = ''
+    runHook preBuild
+    export PINMUX="$(mktemp -d)"
+    ln -s ${libresoc-pinmux} "$PINMUX/ls180"
+    cp ${libresoc-verilog} libresoc/libresoc.v
+    ./versa_ecp5.py --sys-clk-freq=55e6 --build
+    runHook postBuild
+  '';
+
+  installPhase = ''
+    runHook preInstall
+    mv /build/florent/build/versa_ecp5/gateware/versa_ecp5.svf $out
+    runHook postInstall
+  '';
+
+  fixupPhase = "true";
+}
diff --git a/nix/ieee754fpu.nix b/nix/ieee754fpu.nix
new file mode 100644 (file)
index 0000000..e520437
--- /dev/null
@@ -0,0 +1,27 @@
+{ lib, buildPythonPackage, libresoc-nmutil, bigfloat, fetchgit }:
+
+buildPythonPackage {
+  pname = "libresoc-ieee754fpu";
+  version = "unstable-2021-06-05";
+
+  src = fetchgit {
+    url = "https://git.libre-soc.org/git/ieee754fpu.git";
+    rev = "c62fa3a7ee95832587d7725729dcdb9a002ae015";
+    sha256 = "wbr1vGFzUlUtBT6IcRsykADYeksiVoq/LacU/dbRQ0o=";
+  };
+
+  propagatedBuildInputs = [ libresoc-nmutil bigfloat ];
+
+  doCheck = false;
+
+  prePatch = ''
+    touch ./src/ieee754/part/__init__.py
+  '';
+
+  pythonImportsCheck = [ "ieee754.part" ];
+
+  meta = with lib; {
+    homepage = "https://pypi.org/project/libresoc-ieee754fpu/";
+    license = licenses.lgpl3Plus;
+  };
+}
diff --git a/nix/litex.toml b/nix/litex.toml
new file mode 100644 (file)
index 0000000..89317f0
--- /dev/null
@@ -0,0 +1,89 @@
+[litex]
+github_user = "enjoy-digital"
+github_repo = "litex"
+git_revision = "42d8fc226a4f4e8dfef104257a95f98eb9b10da7"
+github_archive_nix_hash = "16zb7mci2a09jc5bbr4342pn95iyl84705n566alpx696xk2l0zr"
+
+[litex-boards]
+github_user = "litex-hub"
+github_repo = "litex-boards"
+git_revision = "1781be166aee867421e0d943f6a62c3397524563"
+github_archive_nix_hash = "0ar41ibs6si03iyhcjn3blw1rkdsazn5rsa95ph8v061kg2yjbjh"
+
+[liteeth]
+github_user = "enjoy-digital"
+github_repo = "liteeth"
+git_revision = "64b85e621e740b9b7a9bdb03749758c703fea6e1"
+github_archive_nix_hash = "1gbscl36n6mgaz1y1b27nzhykrhrccl6ls5vp7dd6divpqdf328i"
+
+[litedram]
+github_user = "enjoy-digital"
+github_repo = "litedram"
+git_revision = "ac825e51124e926c67455292cd2b949954fc6f65"
+github_archive_nix_hash = "1acs4kgbsv8pgml1q7709afh46f8mpy8b1nw0p9n8a1zih8ang1r"
+
+[litehyperbus]
+github_user = "litex-hub"
+github_repo = "litehyperbus"
+git_revision = "c4b64d2c992cedf3e03ffdf87f389feb5ddfff52"
+github_archive_nix_hash = "1iwjwzz4wa9zzm6yqa7rkag9igmsawp8wpmkj6fqia20b7xjglnb"
+
+[liteiclink]
+github_user = "enjoy-digital"
+github_repo = "liteiclink"
+git_revision = "efd200fa9e625144131a310fc09fd1fecf1682e6"
+github_archive_nix_hash = "0g643ryfzc6iq0p80rhq116n5w6mh4fv4yg4adyy5i1vy2grlg8s"
+
+[litepcie]
+github_user = "enjoy-digital"
+github_repo = "litepcie"
+git_revision = "0718fd135fc30e0a3598eaf66ce2fcb54b62193c"
+github_archive_nix_hash = "1m3i4hv49438ik4qhdp7rx9nan5rddrqp7nzvya9xfbh7lfc59hl"
+
+[litescope]
+github_user = "enjoy-digital"
+github_repo = "litescope"
+git_revision = "2739d5a069386c8e834c7f660dce9f93dc2b4598"
+github_archive_nix_hash = "08r7dzlmlfs9pmfz4xkf61sal5zy3caby88bcb4993c43nzpw8a3"
+
+[litesdcard]
+github_user = "enjoy-digital"
+github_repo = "litesdcard"
+git_revision = "edee2467fcabc62c4b34e3daa2271a71e52ba09f"
+github_archive_nix_hash = "0n5x9cx61xij0hc61slabxa05pzmw8i5fyg54ydmxi2fl2p5p0rs"
+
+[litespi]
+github_user = "litex-hub"
+github_repo = "litespi"
+git_revision = "c0730ebdb3c976618bf24e9ec04911e7c9934adf"
+github_archive_nix_hash = "015irjdpii514aj4av02pglvvq0wgxkplyy09435crzy9j5i5v04"
+
+[pythondata-misc-tapcfg]
+github_user = "litex-hub"
+github_repo = "pythondata-misc-tapcfg"
+git_revision = "25c97a4a9ff9af85248028fe01e2c65b2e3640ee"
+github_archive_nix_hash = "0zr6d5giqzsjmqpfyf1b25r0y70bj09xjbfinfxcdc6s8cwwwz71"
+
+[pythondata-software-compiler_rt]
+github_user = "litex-hub"
+github_repo = "pythondata-software-compiler_rt"
+git_revision = "7cfcaed2e726027fd622650b58dd77e47c495ee0"
+github_archive_nix_hash = "0b65dj95418j4pjqqkqjq5npnn1ih1789ba9575kxcljgj7r8xb7"
+
+[pythondata-cpu-serv]
+github_user = "litex-hub"
+github_repo = "pythondata-cpu-serv"
+git_revision = "915cdf793395ab48cc52c0225660eb6eeff41133"
+github_archive_nix_hash = "1ndkjhh7r521cc9g63pmjvgvv9sa3s8n2mkdli91nr7ns3q3lxmk"
+
+[litevideo]
+github_user = "enjoy-digital"
+github_repo = "litevideo"
+git_revision = "41f30143075ece3fff5c33a332ed067d1837cbb3"
+github_archive_nix_hash = "06vw4rn8xby8is13275bmkrxlwp3wlznbdqfay78a5m8bp73kypy"
+
+[valentyusb-hw_cdc_eptri]
+github_user = "litex-hub"
+github_repo = "valentyusb"
+git_revision = "a0526ad053c394306ad7a585a7ddd463831ad09d"
+github_archive_nix_hash = "0nad2x5j5rnjyciwm0abxhzng8nrv06ri8g9qdi39zk8n9zy7cmf"
diff --git a/nix/ls180.nix b/nix/ls180.nix
new file mode 100644 (file)
index 0000000..028fbcb
--- /dev/null
@@ -0,0 +1,44 @@
+{ version }:
+
+{ stdenv, python3Packages, yosys, libresoc-verilog, libresoc-pinmux, pkgsCross }:
+
+stdenv.mkDerivation {
+  pname = "libresoc-ls1804k";
+  inherit version;
+
+  src = ../src/soc/litex/florent;
+
+  nativeBuildInputs =
+    (with python3Packages; [
+    python libresoc-soc litex litedram liteeth liteiclink litescope litesdcard
+    ])
+    ++ [ pkgsCross.powernv.buildPackages.gcc ];
+
+  postPatch = ''
+    patchShebangs --build .
+  '';
+
+  configurePhase = "true";
+
+  buildPhase = ''
+    runHook preBuild
+    export PINMUX="$(mktemp -d)"
+    ln -s ${libresoc-pinmux} "$PINMUX/ls180"
+    cp ${libresoc-verilog} libresoc/libresoc.v
+    ./ls180soc.py --build --platform=ls180sram4k --num-srams=2 --srams4k
+    runHook postBuild
+  '';
+
+  installPhase = ''
+    runHook preInstall
+    mkdir $out
+    mv build/ls180sram4k/gateware/ls180sram4k.v $out/ls180.v
+    mv build/ls180sram4k/gateware/mem.init $out
+    mv build/ls180sram4k/gateware/mem_1.init $out
+    mv libresoc/libresoc.v $out
+    mv libresoc/SPBlock_512W64B8W.v $out
+    runHook postInstall
+  '';
+
+  fixupPhase = "true";
+}
diff --git a/nix/modgrammar.nix b/nix/modgrammar.nix
new file mode 100644 (file)
index 0000000..ce0f348
--- /dev/null
@@ -0,0 +1,20 @@
+{ lib, buildPythonPackage, fetchFromGitHub }:
+
+buildPythonPackage rec {
+  pname = "modgrammar";
+  version = "unstable-2020-09-20";
+
+  src = fetchFromGitHub {
+    owner = "bloerwald";
+    repo = "modgrammar";
+    rev = "d363ad5a86584e560a8b03cbe11c0168d7610691";
+    sha256 = "SO2qjfEVaJfgbA5HLJYwXlaeUzt5EFoljYQ2SsdDCbc=";
+  };
+
+  doCheck = false;
+
+  meta = with lib; {
+    homepage = "https://pypi.org/project/modgrammar/";
+    # license = licenses.bsd; # FIXME: Which BSD?
+  };
+}
diff --git a/nix/nmutil.nix b/nix/nmutil.nix
new file mode 100644 (file)
index 0000000..3489e77
--- /dev/null
@@ -0,0 +1,21 @@
+{ lib, buildPythonPackage, bigfloat, fetchgit, pyvcd }:
+
+buildPythonPackage {
+  pname = "libresoc-nmutil";
+  version = "unstable-2021-08-24";
+
+  propagatedBuildInputs = [ pyvcd ];
+
+  src = fetchgit {
+    url = "https://git.libre-soc.org/git/nmutil.git";
+    rev = "efda080db6978d249a23003bec734f1cc07de329";
+    sha256 = "nTgUiZc4CC0VoUND29kHSIyMlP9IB3oZfehutoNK07w=";
+  };
+
+  doCheck = false;
+
+  meta = with lib; {
+    homepage = "https://pypi.org/project/libresoc-ieee754fpu/";
+    license = licenses.lgpl3Plus;
+  };
+}
diff --git a/nix/openpower-isa.nix b/nix/openpower-isa.nix
new file mode 100644 (file)
index 0000000..5aee8b1
--- /dev/null
@@ -0,0 +1,31 @@
+{ lib, python, buildPythonPackage, fetchgit, libresoc-nmutil, astor, nmigen, ply, pygdbmi }:
+
+buildPythonPackage {
+  pname = "libresoc-openpower-isa";
+  version = "unstable-2021-09-04";
+
+  src = fetchgit {
+    url = "https://git.libre-soc.org/git/openpower-isa.git";
+    rev = "6e43a194f3d07ed5a8daa297187a32746c4c4d3c";
+    sha256 = "0EekUouTQruTXGO5jlPJtqh0DOudghILy0nca5eaZz8=";
+  };
+
+  propagatedBuildInputs = [ libresoc-nmutil astor nmigen ply pygdbmi ];
+
+  doCheck = false;
+
+  prePatch = ''
+    touch ./src/openpower/sv/__init__.py # TODO: fix upstream
+  '';
+
+  postInstall = ''
+    cp -rT ./openpower $out/${python.sitePackages}/../openpower/
+  '';
+
+  pythonImportsCheck = [ "openpower.decoder.power_decoder2" "openpower" ];
+
+  meta = with lib; {
+    homepage = "https://pypi.org/project/libresoc-openpower-isa/";
+    license = licenses.lgpl3Plus;
+  };
+}
diff --git a/nix/pinmux.nix b/nix/pinmux.nix
new file mode 100644 (file)
index 0000000..fc9ca7e
--- /dev/null
@@ -0,0 +1,28 @@
+{ version }:
+
+{ stdenv, python2 }:
+
+stdenv.mkDerivation {
+  pname = "libresoc-pinmux";
+  inherit version;
+
+  src = ../pinmux;
+
+  nativeBuildInputs = [ python2 ];
+
+  configurePhase = "true";
+
+  buildPhase = ''
+    runHook preBuild
+    python src/pinmux_generator.py -v -s ls180 -o ls180
+    runHook postBuild
+  '';
+
+  installPhase = ''
+    runHook preInstall
+    mv ls180 $out
+    runHook postInstall
+  '';
+
+  fixupPhase = "true";
+}
diff --git a/nix/soc.nix b/nix/soc.nix
new file mode 100644 (file)
index 0000000..a4ed136
--- /dev/null
@@ -0,0 +1,38 @@
+{ version }:
+
+{ lib, buildPythonPackage, yosys, runCommand, c4m-jtag, nmigen-soc
+, libresoc-ieee754fpu, libresoc-openpower-isa, python }:
+
+let
+  # If we use ../. as source, then any change to
+  # any unrelated Nix file would cause a rebuild,
+  # since the build would have access to it.
+  src = runCommand "libresoc-soc-source" {} ''
+    mkdir $out
+    cp -r ${../src} -T $out/src
+    cp -r ${../setup.py} -T $out/setup.py
+    cp -r ${../README.md} -T $out/README.md
+    cp -r ${../NEWS.txt} -T $out/NEWS.txt
+  '';
+in
+buildPythonPackage {
+  pname = "libresoc-soc";
+  inherit version src;
+
+  propagatedBuildInputs = [
+    c4m-jtag nmigen-soc python libresoc-ieee754fpu libresoc-openpower-isa yosys
+  ];
+
+  doCheck = false;
+
+  prePatch = ''
+    rm -r src/soc/litex
+  '';
+
+  pythonImportsCheck = [ "soc" ];
+
+  meta = with lib; {
+    homepage = "https://libre-soc.org/";
+    license = licenses.lgpl3Plus;
+  };
+}
diff --git a/nix/verilog.nix b/nix/verilog.nix
new file mode 100644 (file)
index 0000000..600b693
--- /dev/null
@@ -0,0 +1,20 @@
+{ version }:
+
+{ runCommand, python3Packages, libresoc-pinmux }:
+
+let script = ''
+  mkdir pinmux
+  ln -s ${libresoc-pinmux} pinmux/ls180
+  export PINMUX="$(realpath ./pinmux)"
+  python3 -m soc.simple.issuer_verilog \
+    --debug=jtag --enable-core --enable-pll \
+    --enable-xics --enable-sram4x4kblock --disable-svp64 \
+    $out
+''; in
+runCommand "libresoc.v" {
+  inherit version;
+
+  nativeBuildInputs = (with python3Packages; [
+    libresoc-soc
+  ]) ++ [ libresoc-pinmux ];
+} script
diff --git a/pinmux b/pinmux
index 096caad8418250693c93ccf90047750704adcaa7..d96f737c0a53dde983060522816bbef016b449ce 160000 (submodule)
--- a/pinmux
+++ b/pinmux
@@ -1 +1 @@
-Subproject commit 096caad8418250693c93ccf90047750704adcaa7
+Subproject commit d96f737c0a53dde983060522816bbef016b449ce
index a1828c6a4aa434650270ec5421737ea11ee65aa8..03cfa974b957f654512d8ff204ce1262ce7d632f 100644 (file)
@@ -62,7 +62,8 @@ def load_pinouts(chipname=None):
     pth = os.path.split(pth)[0]
 
     # path is relative to this filename, in the pinmux submodule
-    fname = "%s/../../../pinmux/%s/litex_pinpads.json" % (pth, chipname)
+    pinmux = os.getenv("PINMUX", "%s/../../../pinmux" % pth)
+    fname = "%s/%s/litex_pinpads.json" % (pinmux, chipname)
     with open(fname) as f:
         txt = f.read()
 
index 149d3bb7cbf3abf2876e445198e6b314e9b0b257..eea6532664689c0321390371ddc0a9f6a1571c1d 100644 (file)
@@ -17,7 +17,6 @@ def wait_busy(port, no=False,debug=None):
             break
         yield
         cnt += 1
-        
 
 
 def wait_addr(port,debug=None):
@@ -43,12 +42,13 @@ def wait_ldok(port):
         yield
 
 
-def pi_st(port1, addr, data, datalen, msr_pr=0):
+def pi_st(port1, addr, data, datalen, msr_pr=0, is_dcbz=0):
 
     # have to wait until not busy
     yield from wait_busy(port1, no=False)    # wait until not busy
 
     # set up a ST on the port.  address first:
+    yield port1.is_dcbz_i.eq(is_dcbz)  # reset dcbz too
     yield port1.is_st_i.eq(1)  # indicate ST
     yield port1.data_len.eq(datalen)  # ST length (1/2/4/8)
     yield port1.msr_pr.eq(msr_pr)  # MSR PR bit (1==>virt, 0==>real)
@@ -69,43 +69,10 @@ def pi_st(port1, addr, data, datalen, msr_pr=0):
     # can go straight to reset.
     yield port1.is_st_i.eq(0)  # end
     yield port1.addr.ok.eq(0)  # set !ok
-    yield port1.is_dcbz.eq(0)  # reset dcbz too
+    yield port1.is_dcbz_i.eq(0)  # reset dcbz too
 
 
-# copy of pi_st
-def pi_dcbz(port1, addr, msr_pr=0):
-
-    # have to wait until not busy
-    yield from wait_busy(port1, no=False,debug="busy")    # wait until not busy
-
-    # set up a ST on the port.  address first:
-    yield port1.is_st_i.eq(1)  # indicate ST
-    yield port1.msr_pr.eq(msr_pr)  # MSR PR bit (1==>virt, 0==>real)
-
-    yield port1.is_dcbz.eq(1) # set dcbz
-
-    yield port1.addr.data.eq(addr)  # set address
-    yield port1.addr.ok.eq(1)  # set ok
-    yield Settle()
-
-    # guess: this is not needed
-    # yield from wait_addr(port1,debug="addr")             # wait until addr ok
-
-    # just write some dummy data -- remove
-    print("dummy write begin")
-    yield port1.st.data.eq(0)
-    yield port1.st.ok.eq(1)
-    yield
-    yield port1.st.ok.eq(0)
-    print("dummy write end")
-
-    yield from wait_busy(port1, no=True, debug="not_busy")    # wait while busy
-
-    # can go straight to reset.
-    yield port1.is_st_i.eq(0)  # end
-    yield port1.addr.ok.eq(0)  # set !ok
-    yield port1.is_dcbz.eq(0)  # reset dcbz too
-
+# copy of pi_st removed
 
 def pi_ld(port1, addr, datalen, msr_pr=0):
 
index d95dfa52610c708657d65e352448eba2b756c4e2..833112e36607a6450da4fa9cb0d9588ea9346a7f 100644 (file)
@@ -20,6 +20,11 @@ Loads are activated when Go_Write[0] is enabled.  The EA is computed,
 and (as long as there was no exception) the data comes out (at any
 time from the PortInterface), and is captured by the LDCompSTUnit.
 
+TODO: dcbz, yes, that's going to be complicated, has to be done
+ with great care, to detect the case when dcbz is set
+ and *not* expect to read any data, just the address.
+ so, wait for RA but not RB.
+
 Both LD and ST may request that the address be computed from summing
 operand1 (src[0]) with operand2 (src[1]) *or* by summing operand1 with
 the immediate (from the opcode).
@@ -53,6 +58,8 @@ the nested FSMs below are *combinatorial*).
 
     * A third FSM activates to cover ST.  it activates if op_is_st is true
 
+    * TODO document DCBZ (not complete yet)
+
     * The "overall" (fourth) FSM coordinates the progression and completion
       of the three other FSMs, firing "WR_RESET" which switches off "busy"
 
@@ -275,6 +282,7 @@ class LDSTCompUnit(RegSpecAPI, Elaboratable):
         # opcode decode
         op_is_ld = Signal(reset_less=True)
         op_is_st = Signal(reset_less=True)
+        op_is_dcbz = Signal(reset_less=True)
 
         # ALU/LD data output control
         alu_valid = Signal(reset_less=True)  # ALU operands are valid
@@ -321,10 +329,12 @@ class LDSTCompUnit(RegSpecAPI, Elaboratable):
 
         # decode bits of operand (latched)
         oper_r = CompLDSTOpSubset(name="oper_r")  # Dest register
-        comb += op_is_st.eq(oper_r.insn_type == MicrOp.OP_STORE)  # ST
-        comb += op_is_ld.eq(oper_r.insn_type == MicrOp.OP_LOAD)  # LD
-        comb += Display("compldst_multi: op_is_dcbz = %i",
-                        (oper_r.insn_type == MicrOp.OP_DCBZ))
+        comb += op_is_st.eq(oper_r.insn_type == MicrOp.OP_STORE)   # ST
+        comb += op_is_ld.eq(oper_r.insn_type == MicrOp.OP_LOAD)    # LD
+        comb += op_is_dcbz.eq(oper_r.insn_type == MicrOp.OP_DCBZ)  # DCBZ
+        #uncomment if needed
+        #comb += Display("compldst_multi: op_is_dcbz = %i",
+        #                (oper_r.insn_type == MicrOp.OP_DCBZ))
         op_is_update = oper_r.ldst_mode == LDSTMode.update           # UPDATE
         op_is_cix = oper_r.ldst_mode == LDSTMode.cix           # cache-inhibit
         comb += self.load_mem_o.eq(op_is_ld & self.go_ad_i)
@@ -512,9 +522,13 @@ class LDSTCompUnit(RegSpecAPI, Elaboratable):
         # connect to LD/ST PortInterface.
         comb += pi.is_ld_i.eq(op_is_ld & busy_o)  # decoded-LD
         comb += pi.is_st_i.eq(op_is_st & busy_o)  # decoded-ST
+        comb += pi.is_dcbz_i.eq(op_is_dcbz & busy_o)  # decoded-DCBZ
         comb += pi.data_len.eq(oper_r.data_len)  # data_len
         # address: use sync to avoid long latency
         sync += pi.addr.data.eq(addr_r)           # EA from adder
+        sync += Display("EA from adder %i op_is_dcbz %i",addr_r,op_is_dcbz)
+        ## do not use ### sync += pi.is_dcbz.eq(op_is_dcbz) # set dcbz
+
         sync += pi.addr.ok.eq(alu_ok & lsd_l.q)  # "do address stuff" (once)
         comb += self.exc_o.eq(pi.exc_o)  # exception occurred
         comb += addr_ok.eq(self.pi.addr_ok_o)  # no exc, address fine
@@ -673,7 +687,7 @@ def load(dut, src1, src2, imm, imm_ok=True, update=False, zero_a=False,
     yield dut.src1_i.eq(src1)
     yield dut.src2_i.eq(src2)
     yield dut.oper_i.zero_a.eq(zero_a)
-    yield dut.oper_i.imm_data.imm.eq(imm)
+    yield dut.oper_i.imm_data.data.eq(imm)
     yield dut.oper_i.imm_data.ok.eq(imm_ok)
     yield dut.issue_i.eq(1)
     yield
@@ -689,9 +703,9 @@ def load(dut, src1, src2, imm, imm_ok=True, update=False, zero_a=False,
 
     # wait for the operands (RA, RB, or both)
     if rd:
-        yield dut.rd.go.eq(rd)
+        yield dut.rd.go_i.eq(rd)
         yield from wait_for(dut.rd.rel_o)
-        yield dut.rd.go.eq(0)
+        yield dut.rd.go_i.eq(0)
 
     yield from wait_for(dut.adr_rel_o, False, test1st=True)
     # yield dut.ad.go.eq(1)
index 751d2551a7729ccfa3ee444ba3528eeb2b55650f..cccb21330a872721aa1ffa7a4eaa2a3b318d5aeb 100644 (file)
@@ -46,7 +46,7 @@ class Pi2LSUI(PortInterfaceBase):
         self.lsui_busy = Signal()
         self.valid_l = SRLatch(False, name="valid")
 
-    def set_wr_addr(self, m, addr, mask, misalign, msr_pr):
+    def set_wr_addr(self, m, addr, mask, misalign, msr_pr, is_dcbz):
         m.d.comb += self.valid_l.s.eq(1)
         m.d.comb += self.lsui.x_mask_i.eq(mask)
         m.d.comb += self.lsui.x_addr_i.eq(addr)
index 3d6dc8c79bcb69fbc4427767ba1a250a9a10a18f..20695273fecd7faa8bd44688886f71d55a8a288a 100644 (file)
@@ -31,6 +31,7 @@ from soc.experiment.mem_types import LDSTException
 # for testing purposes
 from soc.experiment.testmem import TestMemory
 #from soc.scoreboard.addr_split import LDSTSplitter
+from nmutil.util import Display
 
 import unittest
 
@@ -96,8 +97,8 @@ class PortInterface(RecordObject):
         RecordObject.__init__(self, name=name)
 
         # distinguish op type (ld/st)
-        self.is_ld_i = Signal(reset_less=True)
-        self.is_st_i = Signal(reset_less=True)
+        self.is_ld_i    = Signal(reset_less=True)
+        self.is_st_i    = Signal(reset_less=True)
 
         # LD/ST data length (TODO: other things may be needed)
         self.data_len = Signal(4, reset_less=True)
@@ -115,13 +116,13 @@ class PortInterface(RecordObject):
         self.st = Data(regwid, "st_data_i")  # ok to be set by CompUnit
 
         # additional "modes"
-        self.is_dcbz        = Signal()  # data cache block zero request
         self.is_nc         = Signal()  # no cacheing
         self.msr_pr        = Signal()  # 1==virtual, 0==privileged
+        self.is_dcbz_i     = Signal(reset_less=True)
 
         # mmu
         self.mmu_done          = Signal() # keep for now
-       
+
         # dcache
         self.ldst_error        = Signal()
         ## Signalling ld/st error - NC cache hit, TLB miss, prot/RC failure
@@ -132,7 +133,7 @@ class PortInterface(RecordObject):
         return [self.is_ld_i.eq(inport.is_ld_i),
                 self.is_st_i.eq(inport.is_st_i),
                 self.is_nc.eq(inport.is_nc),
-                self.is_dcbz.eq(inport.is_dcbz),
+                self.is_dcbz_i.eq(inport.is_dcbz_i),
                 self.data_len.eq(inport.data_len),
                 self.go_die_i.eq(inport.go_die_i),
                 self.addr.data.eq(inport.addr.data),
@@ -172,7 +173,7 @@ class PortInterfaceBase(Elaboratable):
     def connect_port(self, inport):
         return self.pi.connect_port(inport)
 
-    def set_wr_addr(self, m, addr, mask, misalign, msr_pr): pass
+    def set_wr_addr(self, m, addr, mask, misalign, msr_pr, is_dcbz): pass
     def set_rd_addr(self, m, addr, mask, misalign, msr_pr): pass
     def set_wr_data(self, m, data, wen): pass
     def get_rd_data(self, m): pass
@@ -254,7 +255,8 @@ class PortInterfaceBase(Elaboratable):
             comb += lenexp.len_i.eq(pi.data_len)
             comb += lenexp.addr_i.eq(lsbaddr)
             with m.If(pi.addr.ok):
-                self.set_wr_addr(m, pi.addr.data, lenexp.lexp_o, misalign, pr)
+                self.set_wr_addr(m, pi.addr.data, lenexp.lexp_o, misalign, pr,
+                                 pi.is_dcbz_i)
                 with m.If(adrok_l.qn):
                     comb += pi.addr_ok_o.eq(1)  # acknowledge addr ok
                     sync += adrok_l.s.eq(1)       # and pull "ack" latch
@@ -295,7 +297,7 @@ class PortInterfaceBase(Elaboratable):
 
         # after waiting one cycle (reset_l is "sync" mode), reset the port
         with m.If(reset_l.q):
-            comb += ld_active.r.eq(1)   # leave the ST active for 1 cycle
+            comb += ld_active.r.eq(1)   # leave the LD active for 1 cycle
             comb += st_active.r.eq(1)   # leave the ST active for 1 cycle
             comb += reset_l.r.eq(1)     # clear reset
             comb += adrok_l.r.eq(1)     # address reset
diff --git a/src/soc/experiment/test/pagetables.py b/src/soc/experiment/test/pagetables.py
new file mode 100644 (file)
index 0000000..53bc039
--- /dev/null
@@ -0,0 +1,25 @@
+def b(x): # byte-reverse function
+    return int.from_bytes(x.to_bytes(8, byteorder='little'),
+                          byteorder='big', signed=False)
+
+test1 = {
+           0x10000:    # PARTITION_TABLE_2
+                       # PATB_GR=1 PRTB=0x1000 PRTS=0xb
+           b(0x800000000100000b),
+
+           0x30000:     # RADIX_ROOT_PTE
+                        # V = 1 L = 0 NLB = 0x400 NLS = 9
+           b(0x8000000000040009),
+
+           0x40000:     # RADIX_SECOND_LEVEL
+                        # V = 1 L = 1 SW = 0 RPN = 0
+                        # R = 1 C = 1 ATT = 0 EAA 0x7
+           b(0xc000000000000183),
+
+           0x1000000:   # PROCESS_TABLE_3
+                        # RTS1 = 0x2 RPDB = 0x300 RTS2 = 0x5 RPDS = 13
+           b(0x40000000000300ad),
+
+           #0x10004: 0
+
+}
index cb0ce66c4522cab0a3a19511d5cfd26292cd0218..b5d6959734b0fd67ef2db27aa187a3af39f8b89a 100644 (file)
@@ -1,35 +1,47 @@
-# test case for LOAD / STORE Computation Unit.
+# test case for LOAD / STORE Computation Unit using MMU
 
-
-from nmigen.compat.sim import run_simulation
+#from nmigen.compat.sim import run_simulation
+from nmigen.sim import Simulator, Delay, Settle
 from nmigen.cli import verilog, rtlil
 from nmigen import Module, Signal, Mux, Cat, Elaboratable, Array, Repl
 from nmigen.hdl.rec import Record, Layout
 
-"""
 from nmutil.latch import SRLatch, latchregister
 from nmutil.byterev import byte_reverse
 from nmutil.extend import exts
-
+from nmutil.util import wrap
 from soc.fu.regspec import RegSpecAPI
 
 from openpower.decoder.power_enums import MicrOp, Function, LDSTMode
 from soc.fu.ldst.ldst_input_record import CompLDSTOpSubset
 from openpower.decoder.power_decoder2 import Data
 from openpower.consts import MSR
-"""
 
 from soc.experiment.compalu_multi import go_record, CompUnitRecord
 from soc.experiment.l0_cache import PortInterface
 from soc.experiment.pimem import LDSTException
-from soc.experiment.compldst_multi import LDSTCompUnit
+from soc.experiment.compldst_multi import LDSTCompUnit, load, store
 from soc.config.test.test_loadstore import TestMemPspec
 
+from soc.experiment.mmu import MMU
+from nmutil.util import Display
+
+from soc.config.loadstore import ConfigMemoryPortInterface
+from soc.experiment.test import pagetables
+from soc.experiment.test.test_wishbone import wb_get
+
 ########################################
 
+# same thing as soc/src/soc/experiment/test/test_dcbz_pi.py
 def ldst_sim(dut):
-    print("TODO")
+    yield dut.mmu.rin.prtbl.eq(0x1000000) # set process table
+    addr = 0x100e0
+    data = 0xf553b658ba7e1f51
+
+    yield from store(dut, addr, 0, data, 0)
     yield
+    #TODO
+    dut.stop = True # stop simulation
 
 ########################################
 
@@ -74,20 +86,39 @@ class TestLDSTCompUnitRegSpecMMU(LDSTCompUnit):
         from soc.experiment.l0_cache import TstL0CacheBuffer
         from soc.fu.ldst.pipe_data import LDSTPipeSpec
         regspec = LDSTPipeSpec.regspec
-        self.l0 = l0 = TstL0CacheBuffer(pspec)
-        pi = l0.l0.dports[0]
-        LDSTCompUnit.__init__(self, pi, regspec, 4)
+
+        # use a LoadStore1 here
+
+        cmpi = ConfigMemoryPortInterface(pspec)
+        self.cmpi = cmpi
+        ldst = cmpi.pi
+        self.l0 = ldst
+
+        self.mmu = MMU()
+        LDSTCompUnit.__init__(self, ldst.pi, regspec, 4)
 
     def elaborate(self, platform):
         m = LDSTCompUnit.elaborate(self, platform)
         m.submodules.l0 = self.l0
+        m.submodules.mmu = self.mmu
         # link addr-go direct to rel
         m.d.comb += self.ad.go_i.eq(self.ad.rel_o)
+
+        # link mmu and dcache together
+        dcache = self.l0.dcache
+        mmu = self.mmu
+        m.d.comb += dcache.m_in.eq(mmu.d_out) # MMUToDCacheType
+        m.d.comb += mmu.d_in.eq(dcache.m_out) # DCacheToMMUType
+
         return m
 
 
+
+
 def test_scoreboard_regspec_mmu():
 
+    m = Module()
+
     units = {}
     pspec = TestMemPspec(ldst_ifacetype='mmu_cache_wb',
                          imem_ifacetype='bare_wb',
@@ -97,11 +128,19 @@ def test_scoreboard_regspec_mmu():
                          units=units)
 
     dut = TestLDSTCompUnitRegSpecMMU(pspec)
-    vl = rtlil.convert(dut, ports=dut.ports())
-    with open("test_ldst_comp_mmu2.il", "w") as f:
-        f.write(vl)
 
-    run_simulation(dut, ldst_sim(dut), vcd_name='test_ldst_regspec.vcd')
+    m.submodules.dut = dut
+
+    sim = Simulator(m)
+    sim.add_clock(1e-6)
+
+    dut.mem = pagetables.test1
+    dut.stop = False
+
+    sim.add_sync_process(wrap(ldst_sim(dut)))
+    sim.add_sync_process(wrap(wb_get(dut)))
+    with sim.write_vcd('test_scoreboard_regspec_mmu'):
+        sim.run()
 
 
 if __name__ == '__main__':
index 2644a65f7e046e142a94f04a8b399fa73d5ff657..b3e531d98133749f9462baff963855f38cfe4ede 100644 (file)
@@ -8,28 +8,22 @@ from nmigen.cli import rtlil
 from nmutil.mask import Mask, masked
 from nmutil.util import Display
 from random import randint, seed
-
-if True:
-    from nmigen.back.pysim import Simulator, Delay, Settle
-else:
-    from nmigen.sim.cxxsim import Simulator, Delay, Settle
+from nmigen.sim import Simulator, Delay, Settle
 from nmutil.util import wrap
 
-from soc.config.test.test_pi2ls import pi_ld, pi_st, pi_ldst, pi_dcbz
+from soc.config.test.test_pi2ls import pi_ld, pi_st, pi_ldst
 from soc.config.test.test_loadstore import TestMemPspec
 from soc.config.loadstore import ConfigMemoryPortInterface
 
 from soc.fu.ldst.loadstore import LoadStore1
 from soc.experiment.mmu import MMU
+from soc.experiment.test import pagetables
 
 from nmigen.compat.sim import run_simulation
 
 
-stop = False
 
-def b(x): # byte-reverse function
-    return int.from_bytes(x.to_bytes(8, byteorder='little'),
-                          byteorder='big', signed=False)
+stop = False
 
 def wb_get(wb, mem):
     """simulator process for getting memory load requests
@@ -112,7 +106,7 @@ def setup_mmu():
 
 ### test case for dcbz
 
-def _test_dcbz_addr_zero(dut, mem):
+def _test_dcbz_addr_100e0(dut, mem):
     mmu = dut.submodules.mmu
     pi = dut.submodules.ldst.pi
     global stop
@@ -133,52 +127,32 @@ def _test_dcbz_addr_zero(dut, mem):
     assert ld_data == 0xf553b658ba7e1f51
 
     print("do_dcbz ===============")
-    yield from pi_dcbz(pi, addr, msr_pr=0)
+    yield from pi_st(pi, addr, data, 8, msr_pr=0, is_dcbz=1)
     print("done_dcbz ===============")
     yield
 
     ld_data = yield from pi_ld(pi, addr, 8, msr_pr=0)
     print("ld_data after dcbz")
     print(ld_data)
+    assert ld_data == 0
 
     yield
     stop = True
 
-#FIXME: rename
-def test_dcbz_addr_zero():
+def test_dcbz_addr_100e0():
 
     m, cmpi = setup_mmu()
 
-    mem = {
-           0x10000:    # PARTITION_TABLE_2
-                       # PATB_GR=1 PRTB=0x1000 PRTS=0xb
-           b(0x800000000100000b),
-
-           0x30000:     # RADIX_ROOT_PTE
-                        # V = 1 L = 0 NLB = 0x400 NLS = 9
-           b(0x8000000000040009),
-
-           0x40000:     # RADIX_SECOND_LEVEL
-                        # V = 1 L = 1 SW = 0 RPN = 0
-                        # R = 1 C = 1 ATT = 0 EAA 0x7
-           b(0xc000000000000183),
-
-           0x1000000:   # PROCESS_TABLE_3
-                        # RTS1 = 0x2 RPDB = 0x300 RTS2 = 0x5 RPDS = 13
-           b(0x40000000000300ad),
-           
-           0x10004: 0
-
-    }
+    mem = pagetables.test1
 
     # nmigen Simulation
     sim = Simulator(m)
     sim.add_clock(1e-6)
 
-    sim.add_sync_process(wrap(_test_dcbz_addr_zero(m, mem)))
+    sim.add_sync_process(wrap(_test_dcbz_addr_100e0(m, mem)))
     sim.add_sync_process(wrap(wb_get(cmpi.wb_bus(), mem)))
     with sim.write_vcd('test_dcbz_addr_zero.vcd'):
         sim.run()
 
 if __name__ == '__main__':
-    test_dcbz_addr_zero()
+    test_dcbz_addr_100e0()
index 3dde127ffc18b10d9c2d60647b39021e7d2f7992..5ba926847c771f4a59801c010c6d498e16e845d2 100644 (file)
@@ -25,7 +25,7 @@ class TestCachedMemoryPortInterface(PortInterfaceBase):
         super().__init__(regwid, addrwid)
         self.ldst = LDSTSplitter(32, 48, 4)
 
-    def set_wr_addr(self, m, addr, mask, misalign, msr_pr):
+    def set_wr_addr(self, m, addr, mask, misalign, msr_pr, is_dcbz):
         m.d.comb += self.ldst.addr_i.eq(addr)
 
     def set_rd_addr(self, m, addr, mask, misalign, msr_pr):
index 2f219e63ebbd91043a54f81d8f06f88e9eaf7939..d93bd594e84f52614c8bd1992d941250fdd3444d 100644 (file)
@@ -61,7 +61,7 @@ class TestMicrowattMemoryPortInterface(PortInterfaceBase):
         self.mmu = mmu
         self.dcache = dcache
 
-    def set_wr_addr(self, m, addr, mask, misalign, msr_pr):
+    def set_wr_addr(self, m, addr, mask, misalign, msr_pr, is_dcbz):
         m.d.comb += self.dcache.d_in.addr.eq(addr)
         m.d.comb += self.mmu.l_in.addr.eq(addr)
         m.d.comb += self.mmu.l_in.load.eq(0)
diff --git a/src/soc/experiment/test/test_wishbone.py b/src/soc/experiment/test/test_wishbone.py
new file mode 100644 (file)
index 0000000..fd3279d
--- /dev/null
@@ -0,0 +1,44 @@
+def wb_get(dut):
+    """simulator process for getting memory load requests
+    """
+    mem = dut.mem
+    wb = dut.cmpi.wb_bus()
+
+    while not dut.stop:
+        while True: # wait for dc_valid
+            if dut.stop:
+                return
+            cyc = yield (wb.cyc)
+            stb = yield (wb.stb)
+            if cyc and stb:
+                break
+            yield
+        addr = (yield wb.adr) << 3
+        if addr not in mem:
+            print ("    WB LOOKUP NO entry @ %x, returning zero" % (addr))
+
+        # read or write?
+        we = (yield wb.we)
+        if we:
+            store = (yield wb.dat_w)
+            sel = (yield wb.sel)
+            data = mem.get(addr, 0)
+            # note we assume 8-bit sel, here
+            res = 0
+            for i in range(8):
+                mask = 0xff << (i*8)
+                if sel & (1<<i):
+                    res |= store & mask
+                else:
+                    res |= data & mask
+            mem[addr] = res
+            print ("    DCACHE set %x mask %x data %x" % (addr, sel, res))
+        else:
+            data = mem.get(addr, 0)
+            yield wb.dat_r.eq(data)
+            print ("    DCACHE get %x data %x" % (addr, data))
+
+        yield wb.ack.eq(1)
+        yield
+        yield wb.ack.eq(0)
+        yield
index 4d5fe2313bb9184e63fff9b3f81422650d1d9ba4..f4ad49183c1ffbd686644238a676d7dd807c64b6 100644 (file)
@@ -13,7 +13,7 @@ from nmigen import (Module, Signal, Cat, Repl, Mux, Const)
 from nmutil.pipemodbase import PipeModBase
 from nmutil.extend import exts, extz
 from soc.fu.alu.pipe_data import ALUInputData, ALUOutputData
-from ieee754.part.partsig import PartitionedSignal
+from ieee754.part.partsig import SimdSignal
 from openpower.decoder.power_enums import MicrOp
 
 from openpower.decoder.power_fields import DecodeFields
index 49444e97b1449eeab0e7ea7927aaa51b18c34116..395b268bdc9fe970540bef08d51a78fed57b25ab 100644 (file)
@@ -4,7 +4,7 @@
 from nmigen import (Module, Signal, Cat, Repl)
 from soc.fu.alu.pipe_data import ALUInputData, ALUOutputData
 from soc.fu.common_output_stage import CommonOutputStage
-from ieee754.part.partsig import PartitionedSignal
+from ieee754.part.partsig import SimdSignal
 from openpower.decoder.power_enums import MicrOp
 
 
index dc17410af790998086d38643518860aab0406cd3..45106984a0e1469a255d5ad5e198974c2d37cc70 100644 (file)
@@ -2,7 +2,7 @@
 # and updating the condition register
 from nmigen import (Module, Signal, Cat, Const)
 from nmutil.pipemodbase import PipeModBase
-from ieee754.part.partsig import PartitionedSignal
+from ieee754.part.partsig import SimdSignal
 from openpower.decoder.power_enums import MicrOp
 
 
index 9882a47ee1306cc59cbe382a2c77e44e054d71f1..7885b9f74daea6bbb464ddec6e130f45edcbb225 100644 (file)
@@ -11,6 +11,7 @@ from openpower.decoder.power_decoder import create_pdecode
 from openpower.decoder.power_decoder2 import PowerDecode2, get_rdflags
 from openpower.decoder.power_enums import Function
 from openpower.decoder.isa.all import ISA
+from openpower.decoder.isa.mem import Mem
 
 from soc.experiment.compalu_multi import find_ok  # hack
 from soc.config.test.test_loadstore import TestMemPspec
@@ -137,15 +138,17 @@ def get_l0_mem(l0):  # BLECH! this is awful! hunting around through structures
     return mem.mem
 
 
-def setup_tst_memory(l0, sim):
+def setup_tst_memory(l0, test_mem):
+    # create independent Sim Mem from test values
+    sim_mem = Mem(initial_mem=test_mem)
     mem = get_l0_mem(l0)
     print("before, init mem", mem.depth, mem.width, mem)
     for i in range(mem.depth):
-        data = sim.mem.ld(i*8, 8, False)
+        data = sim_mem.ld(i*8, 8, False)
         print("init ", i, hex(data))
         yield mem._array[i].eq(data)
     yield Settle()
-    for k, v in sim.mem.mem.items():
+    for k, v in sim_mem.mem.items():
         print("    %6x %016x" % (k, v))
     print("before, nmigen mem dump")
     for i in range(mem.depth):
@@ -199,7 +202,7 @@ class TestRunner(FHDLTestCase):
 
         # initialise memory
         if self.funit == Function.LDST:
-            yield from setup_tst_memory(l0, sim)
+            yield from setup_tst_memory(l0, test.mem)
 
         pc = sim.pc.CIA.value
         index = pc//4
index 9f63a63117ac5e0d4a72f4e7d0dc901d721fd504..e271876b26e41b1f74a6bd919dd985691cae00b0 100644 (file)
@@ -3,7 +3,7 @@
 
 from nmigen import (Module, Signal, Cat, Repl, Mux, Const, Array)
 from nmutil.pipemodbase import PipeModBase
-from ieee754.part.partsig import PartitionedSignal
+from ieee754.part.partsig import SimdSignal
 from openpower.decoder.power_enums import MicrOp
 
 from openpower.decoder.power_fields import DecodeFields
index 903770ddd0b50b0dc23c647654adcab265f6126e..31218c66ef0af904704b7cfbbabd397d76290e33 100644 (file)
@@ -8,7 +8,7 @@ from nmigen import (Module, Signal, Cat, Repl, Mux, Const, Array, signed)
 from nmutil.pipemodbase import PipeModBase
 from soc.fu.logical.pipe_data import LogicalInputData
 from soc.fu.div.pipe_data import DivMulOutputData
-from ieee754.part.partsig import PartitionedSignal
+from ieee754.part.partsig import SimdSignal
 from openpower.decoder.power_enums import MicrOp
 
 from openpower.decoder.power_fields import DecodeFields
index 937bcbb029a8ce00231522dd17353637b7d36bc0..0625159e123b67658a7e667327835ec637b2a038 100644 (file)
@@ -4,7 +4,7 @@
 from nmigen import (Module, Signal, Cat, Repl, Mux, Const, Array)
 from nmutil.pipemodbase import PipeModBase
 from soc.fu.div.pipe_data import DivInputData
-from ieee754.part.partsig import PartitionedSignal
+from ieee754.part.partsig import SimdSignal
 from openpower.decoder.power_enums import MicrOp
 
 from openpower.decoder.power_fields import DecodeFields
index d9f0c14a5d293e91a2fc053e182b7e940cdc8394..7400c0ae6eeefacfc92ae9c2783d2c9da5269d52 100644 (file)
@@ -119,18 +119,14 @@ class LoadStore1(PortInterfaceBase):
         #self.nia           = Signal(64)
         #self.srr1          = Signal(16)
 
-    def set_wr_addr(self, m, addr, mask, misalign, msr_pr):
+    def set_wr_addr(self, m, addr, mask, misalign, msr_pr, is_dcbz):
         m.d.comb += self.req.load.eq(0) # store operation
         m.d.comb += self.req.byte_sel.eq(mask)
         m.d.comb += self.req.addr.eq(addr)
         m.d.comb += self.req.priv_mode.eq(~msr_pr) # not-problem  ==> priv
         m.d.comb += self.req.virt_mode.eq(msr_pr) # problem-state ==> virt
         m.d.comb += self.req.align_intr.eq(misalign)
-
-        dcbz = self.pi.is_dcbz
-        with m.If(dcbz):
-            m.d.comb += Display("set_wr_addr: is_dcbz")
-        m.d.comb += self.req.dcbz.eq(dcbz)
+        m.d.comb += self.req.dcbz.eq(is_dcbz)
 
         # option to disable the cache entirely for write
         if self.disable_cache:
index e56f3445f4cd538ede6c72b36995eaf620a5c19e..253664032fc16a1401665416a70e33688c6caa65 100644 (file)
@@ -13,7 +13,7 @@ from soc.fu.logical.pipe_data import LogicalInputData
 from soc.fu.logical.bpermd import Bpermd
 from soc.fu.logical.popcount import Popcount
 from soc.fu.logical.pipe_data import LogicalOutputData
-from ieee754.part.partsig import PartitionedSignal
+from ieee754.part.partsig import SimdSignal
 from openpower.decoder.power_enums import MicrOp
 
 from openpower.decoder.power_fields import DecodeFields
index 73b48d1eecdd33a58245c5fba91685b53c07e52c..81a1c5247de848509bea6b2e577ea78401225e60 100644 (file)
@@ -6,7 +6,7 @@ from nmutil.pipemodbase import PipeModBase
 from soc.fu.common_output_stage import CommonOutputStage
 from soc.fu.logical.pipe_data import (LogicalInputData, LogicalOutputData,
                                       LogicalOutputDataFinal)
-from ieee754.part.partsig import PartitionedSignal
+from ieee754.part.partsig import SimdSignal
 from openpower.decoder.power_enums import MicrOp
 
 
index 68bcf47d5df861ec71708dac7b3b26121a3e4dc4..e2a2727f2c1de56cbdbfa9c72e7dc320166f12cb 100644 (file)
@@ -3,7 +3,7 @@
 from nmigen import Module
 from nmutil.pipemodbase import PipeModBase
 from soc.fu.mul.pipe_data import MulIntermediateData, MulOutputData
-from ieee754.part.partsig import PartitionedSignal
+from ieee754.part.partsig import SimdSignal
 
 
 class MulMainStage2(PipeModBase):
index 0b45c791ade830433a5cde5ce2638d2eb7e07d6e..d7e8df417a4a699861b59ff86705a11b11281dc4 100644 (file)
@@ -10,7 +10,7 @@ from nmigen import (Module, Signal, Cat, Repl, Mux, signed)
 from nmutil.pipemodbase import PipeModBase
 from soc.fu.div.pipe_data import DivMulOutputData
 from soc.fu.mul.pipe_data import MulOutputData
-from ieee754.part.partsig import PartitionedSignal
+from ieee754.part.partsig import SimdSignal
 from openpower.decoder.power_enums import MicrOp
 
 
index f22964dd5b50be0930fe6fa77c1841486b1363e1..c5e696ae415afbe03e294c4f386c22316c34c7d0 100644 (file)
@@ -4,7 +4,7 @@ from nmigen import (Module, Signal, Mux)
 from nmutil.pipemodbase import PipeModBase
 from soc.fu.div.pipe_data import DivInputData
 from soc.fu.mul.pipe_data import MulIntermediateData
-from ieee754.part.partsig import PartitionedSignal
+from ieee754.part.partsig import SimdSignal
 from nmutil.util import eq32
 
 class MulMainStage1(PipeModBase):
index ec56e1fe3e63f03c21b4f6ccb9ac342754b40957..bb9d8d8490235901a78cb1dd3fee08fda5c66ed3 100644 (file)
@@ -59,8 +59,14 @@ def set_alu_inputs(alu, dec2, sim, has_third_input):
         overflow = pia.OverflowFlags(so=bool(so),
                                      ov=False,
                                      ov32=False)
+    immediate_ok = yield dec2.e.do.imm_data.ok
+    if immediate_ok:
+        immediate = yield dec2.e.do.imm_data.data
+    else:
+        immediate = None
     rc = inp["rc"] if has_third_input else None
     return pia.InstructionInput(ra=inp.get("ra"), rb=inp.get("rb"),
+                                immediate=immediate,
                                 rc=rc, overflow=overflow)
 
 
@@ -103,15 +109,7 @@ class MulTestHelper(unittest.TestCase):
             opname = code.split(' ')[0]
             fnname = opname.replace(".", "_")
             print(f"{fnname}({pia_inputs})")
-            pia_res = None
-            try:
-                pia_res = getattr(pia, fnname)(pia_inputs)
-            except AttributeError:
-                EXPECTED_FAILURES = ["mulli"]
-                if fnname not in EXPECTED_FAILURES:
-                    raise
-                else:
-                    print("not implemented, as expected.")
+            pia_res = getattr(pia, fnname)(pia_inputs)
             print(f"-> {pia_res}")
 
             yield from isa_sim.call(opname)
index 0be12d1b2fd08a9a90456fd81eac606c4f0117bc..76550854096324fbae365ff5d263e529474a5977 100644 (file)
@@ -10,7 +10,7 @@ from nmigen import (Module, Signal, Cat, Repl, Mux, Const)
 from nmutil.pipemodbase import PipeModBase
 from soc.fu.shift_rot.pipe_data import (ShiftRotOutputData,
                                        ShiftRotInputData)
-from ieee754.part.partsig import PartitionedSignal
+from ieee754.part.partsig import SimdSignal
 from openpower.decoder.power_enums import MicrOp
 from soc.fu.shift_rot.rotator import Rotator
 
index 6efd2e59703f6f0747435f97030e8a463233457f..42f7357660b245c4491297d24eebc28b4ac2c21f 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 6efd2e59703f6f0747435f97030e8a463233457f
+Subproject commit 42f7357660b245c4491297d24eebc28b4ac2c21f
index 9e69f3b4a3cb9d3941defedd7de72f741201d2a3..c15732d1b5582e2439ed19d4260c25d0c6d22562 100644 (file)
@@ -11,7 +11,8 @@ from nmigen.back.pysim import Simulator, Delay, Settle
 from nmutil.formaltest import FHDLTestCase
 from nmigen.cli import rtlil
 import unittest
-from openpower.test.state import SimState, teststate_check_regs
+from openpower.test.state import (SimState, teststate_check_regs,
+                                  teststate_check_mem)
 from soc.simple.test.teststate import HDLState
 from openpower.decoder.isa.caller import special_sprs
 from openpower.decoder.power_decoder import create_pdecode
@@ -156,6 +157,12 @@ def check_regs(dut, sim, core, test, code):
     yield from teststate_check_regs(dut, testdic, test, code)
 
 
+def check_mem(dut, sim, core, test, code):
+    # create the two states and compare mem
+    testdic = {'sim': sim, 'hdl': core}
+    yield from teststate_check_mem(dut, testdic, test, code)
+
+
 def wait_for_busy_hi(cu):
     while True:
         busy_o = yield cu.busy_o
@@ -225,51 +232,52 @@ class TestRunner(FHDLTestCase):
             for test in self.test_data:
                 print(test.name)
                 program = test.program
-                self.subTest(test.name)
-                sim = ISA(pdecode2, test.regs, test.sprs, test.cr, test.mem,
-                          test.msr,
-                          bigendian=bigendian)
-                gen = program.generate_instructions()
-                instructions = list(zip(gen, program.assembly.splitlines()))
-
-                yield from setup_tst_memory(l0, sim)
-                yield from setup_regs(core, test)
-
-                index = sim.pc.CIA.value // 4
-                while index < len(instructions):
-                    ins, code = instructions[index]
-
-                    print("instruction: 0x{:X}".format(ins & 0xffffffff))
-                    print(code)
-
-                    # ask the decoder to decode this binary data (endian'd)
-                    yield core.bigendian_i.eq(bigendian)  # little / big?
-                    yield instruction.eq(ins)          # raw binary instr.
-                    yield ivalid_i.eq(1)
-                    yield Settle()
-                    # fn_unit = yield pdecode2.e.fn_unit
-                    #fuval = self.funit.value
-                    #self.assertEqual(fn_unit & fuval, fuval)
-
-                    # set operand and get inputs
-                    yield from set_issue(core, pdecode2, sim)
-                    yield Settle()
-
-                    yield from wait_for_busy_clear(core)
-                    yield ivalid_i.eq(0)
-                    yield
-
-                    print("sim", code)
-                    # call simulated operation
-                    opname = code.split(' ')[0]
-                    yield from sim.call(opname)
-                    index = sim.pc.CIA.value // 4
+                with self.subTest(test.name):
+                    sim = ISA(pdecode2, test.regs, test.sprs, test.cr,
+                              test.mem,
+                              test.msr,
+                              bigendian=bigendian)
+                    gen = program.generate_instructions()
+                    instructions = list(zip(gen, program.assembly.splitlines()))
 
-                    # register check
-                    yield from check_regs(self, sim, core, test, code)
+                    yield from setup_tst_memory(l0, test.mem)
+                    yield from setup_regs(core, test)
 
-                    # Memory check
-                    yield from check_sim_memory(self, l0, sim, code)
+                    index = sim.pc.CIA.value // 4
+                    while index < len(instructions):
+                        ins, code = instructions[index]
+
+                        print("instruction: 0x{:X}".format(ins & 0xffffffff))
+                        print(code)
+
+                        # ask the decoder to decode this binary data (endian'd)
+                        yield core.bigendian_i.eq(bigendian)  # little / big?
+                        yield instruction.eq(ins)          # raw binary instr.
+                        yield ivalid_i.eq(1)
+                        yield Settle()
+                        # fn_unit = yield pdecode2.e.fn_unit
+                        #fuval = self.funit.value
+                        #self.assertEqual(fn_unit & fuval, fuval)
+
+                        # set operand and get inputs
+                        yield from set_issue(core, pdecode2, sim)
+                        yield Settle()
+
+                        yield from wait_for_busy_clear(core)
+                        yield ivalid_i.eq(0)
+                        yield
+
+                        print("sim", code)
+                        # call simulated operation
+                        opname = code.split(' ')[0]
+                        yield from sim.call(opname)
+                        index = sim.pc.CIA.value // 4
+
+                        # register check
+                        yield from check_regs(self, sim, core, test, code)
+
+                        # Memory check
+                        yield from check_mem(self, sim, core, test, code)
 
         sim.add_sync_process(process)
         with sim.write_vcd("core_simulator.vcd", "core_simulator.gtkw",
index 2b6fa3e91f5daf0ebdf7bf3d79fc5c585daae5d7..c01e8c68c5c68e4c107c18337f66fcdacf041194 100644 (file)
@@ -23,6 +23,7 @@ from openpower.test.alu.alu_cases import ALUTestCase
 from openpower.test.div.div_cases import DivTestCases
 from openpower.test.logical.logical_cases import LogicalTestCase
 from openpower.test.shift_rot.shift_rot_cases import ShiftRotTestCase
+from openpower.test.shift_rot.shift_rot_cases2 import ShiftRotTestCase2
 from openpower.test.cr.cr_cases import CRTestCase
 from openpower.test.branch.branch_cases import BranchTestCase
 from soc.fu.spr.test.test_pipe_caller import SPRTestCase
@@ -43,7 +44,8 @@ if __name__ == "__main__":
     sys.argv = sys.argv[:1]
 
     if not testing:
-        testing = ['general', 'ldst', 'cr', 'shiftrot', 'logical', 'alu',
+        testing = ['general', 'ldst', 'cr', 'shiftrot', 'shiftrot2',
+                   'logical', 'alu',
                    'branch', 'div']
 
     print ("SVP64 test mode enabled", svp64, testing)
@@ -59,6 +61,7 @@ if __name__ == "__main__":
              'ldst': LDSTTestCase().test_data,
              'cr': CRTestCase().test_data,
              'shiftrot': ShiftRotTestCase().test_data,
+             'shiftrot2': ShiftRotTestCase2().test_data,
              'logical': LogicalTestCase().test_data,
              'alu': ALUTestCase().test_data,
              'branch': BranchTestCase().test_data,
index 7e5013652907ef0509f759dac0c98630bf32a059..1dd89c533d19d5f9f28c9d190fb48ce30000bf29 100644 (file)
@@ -15,8 +15,7 @@ from soc.config.test.test_loadstore import TestMemPspec
 from soc.simple.test.test_core import (setup_regs, check_regs,
                                        wait_for_busy_clear,
                                        wait_for_busy_hi)
-from soc.fu.compunits.test.test_compunit import (setup_tst_memory,
-                                                 check_sim_memory,
+from soc.fu.compunits.test.test_compunit import (check_sim_memory,
                                                  get_l0_mem)
 
 from soc.simple.test.test_runner import setup_i_memory
@@ -112,7 +111,6 @@ class TestRunner(FHDLTestCase):
                 # blech!  put the same listing into the data memory
                 data_mem = get_l0_mem(l0)
                 yield from setup_i_memory(data_mem, pc, instructions)
-                # yield from setup_tst_memory(l0, sim)
                 yield from setup_regs(core, test)
 
                 yield pc_i.eq(pc)
index d1d8e20949a4d7d6474348f67b34c2c2c59643bb..8558303f730d48a6ae37ed2377dfe64ac5714c54 100644 (file)
@@ -5,28 +5,22 @@ related bugs:
  * https://bugs.libre-soc.org/show_bug.cgi?id=363
  * https://bugs.libre-soc.org/show_bug.cgi?id=686#c51
 """
-from nmigen import Module, Signal, Cat, ClockSignal
+from nmigen import Module, Signal
 from nmigen.hdl.xfrm import ResetInserter
+from copy import copy
 
 # NOTE: to use cxxsim, export NMIGEN_SIM_MODE=cxxsim from the shell
 # Also, check out the cxxsim nmigen branch, and latest yosys from git
 from nmutil.sim_tmp_alternative import Simulator, Settle
 
-from nmutil.formaltest import FHDLTestCase
-from nmutil.gtkw import write_gtkw
-from nmigen.cli import rtlil
-from openpower.decoder.isa.caller import special_sprs, SVP64State
+from openpower.decoder.isa.caller import SVP64State
 from openpower.decoder.isa.all import ISA
 from openpower.endian import bigendian
 
-from openpower.decoder.power_decoder import create_pdecode
-from openpower.decoder.power_decoder2 import PowerDecode2
-from soc.regfile.regfiles import StateRegs
-
 from soc.simple.issuer import TestIssuerInternal
 
 from soc.config.test.test_loadstore import TestMemPspec
-from soc.simple.test.test_core import (setup_regs, check_regs,
+from soc.simple.test.test_core import (setup_regs, check_regs, check_mem,
                                        wait_for_busy_clear,
                                        wait_for_busy_hi)
 from soc.fu.compunits.test.test_compunit import (setup_tst_memory,
@@ -34,6 +28,8 @@ from soc.fu.compunits.test.test_compunit import (setup_tst_memory,
 from soc.debug.dmi import DBGCore, DBGCtrl, DBGStat
 from nmutil.util import wrap
 from soc.experiment.test.test_mmu_dcache import wb_get
+from openpower.test.state import TestState, StateRunner
+from openpower.test.runner import TestRunnerBase
 
 
 def setup_i_memory(imem, startaddr, instructions):
@@ -122,358 +118,169 @@ def get_dmi(dmi, addr):
     return data
 
 
-class TestRunner(FHDLTestCase):
-    def __init__(self, tst_data, microwatt_mmu=False, rom=None,
-                        svp64=True):
-        super().__init__("run_all")
-        self.test_data = tst_data
-        self.microwatt_mmu = microwatt_mmu
-        self.rom = rom
-        self.svp64 = svp64
-
-    def run_all(self):
-        m = Module()
-        comb = m.d.comb
-        pc_i = Signal(32)
-        svstate_i = Signal(64)
+class HDLRunner(StateRunner):
+    """HDLRunner:  Implements methods for the setup, preparation, and
+    running of tests using nmigen HDL simulation.
+    """
+    def __init__(self, dut, m, pspec):
+        super().__init__("hdl", HDLRunner)
+
+        self.dut = dut
+        self.pc_i = Signal(32)
+        self.svstate_i = Signal(64)
 
-        if self.microwatt_mmu:
-            ldst_ifacetype = 'test_mmu_cache_wb'
-        else:
-            ldst_ifacetype = 'test_bare_wb'
-        imem_ifacetype = 'test_bare_wb'
-
-        pspec = TestMemPspec(ldst_ifacetype=ldst_ifacetype,
-                             imem_ifacetype=imem_ifacetype,
-                             addr_wid=48,
-                             mask_wid=8,
-                             imem_reg_wid=64,
-                             # wb_data_width=32,
-                             use_pll=False,
-                             nocore=False,
-                             xics=False,
-                             gpio=False,
-                             regreduce=True,
-                             svp64=self.svp64,
-                             mmu=self.microwatt_mmu,
-                             reg_wid=64)
         #hard_reset = Signal(reset_less=True)
-        issuer = TestIssuerInternal(pspec)
+        self.issuer = TestIssuerInternal(pspec)
         # use DMI RESET command instead, this does actually work though
         #issuer = ResetInserter({'coresync': hard_reset,
         #                        'sync': hard_reset})(issuer)
-        m.submodules.issuer = issuer
-        imem = issuer.imem._get_memory()
-        core = issuer.core
-        dmi = issuer.dbg.dmi
-        pdecode2 = issuer.pdecode2
-        l0 = core.l0
-        regreduce_en = pspec.regreduce_en == True
+        m.submodules.issuer = self.issuer
+        self.dmi = self.issuer.dbg.dmi
+
+        comb = m.d.comb
+        comb += self.issuer.pc_i.data.eq(self.pc_i)
+        comb += self.issuer.svstate_i.data.eq(self.svstate_i)
+
+    def prepare_for_test(self, test):
+        self.test = test
+
+        # set up bigendian (TODO: don't do this, use MSR)
+        yield self.issuer.core_bigendian_i.eq(bigendian)
+        yield Settle()
+
+        yield
+        yield
+        yield
+        yield
+
+    def setup_during_test(self):
+        yield from set_dmi(self.dmi, DBGCore.CTRL, 1<<DBGCtrl.STOP)
+        yield
+
+    def run_test(self, instructions):
+        """run_hdl_state - runs a TestIssuer nmigen HDL simulation
+        """
 
-        #simdec = create_pdecode()
-        simdec2 = PowerDecode2(None, regreduce_en=regreduce_en)
-        m.submodules.simdec2 = simdec2  # pain in the neck
+        imem = self.issuer.imem._get_memory()
+        core = self.issuer.core
+        dmi = self.issuer.dbg.dmi
+        pdecode2 = self.issuer.pdecode2
+        l0 = core.l0
+        hdl_states = []
 
-        # run core clock at same rate as test clock
-        intclk = ClockSignal("coresync")
-        comb += intclk.eq(ClockSignal())
+        # establish the TestIssuer context (mem, regs etc)
 
-        comb += issuer.pc_i.data.eq(pc_i)
-        comb += issuer.svstate_i.data.eq(svstate_i)
+        pc = 0  # start address
+        counter = 0  # test to pause/start
 
-        # nmigen Simulation
-        sim = Simulator(m)
-        sim.add_clock(1e-6)
+        yield from setup_i_memory(imem, pc, instructions)
+        yield from setup_tst_memory(l0, self.test.mem)
+        yield from setup_regs(pdecode2, core, self.test)
 
-        def process():
+        # set PC and SVSTATE
+        yield self.pc_i.eq(pc)
+        yield self.issuer.pc_i.ok.eq(1)
 
-            # start in stopped
-            yield from set_dmi(dmi, DBGCore.CTRL, 1<<DBGCtrl.STOP)
-            yield
+        # copy initial SVSTATE
+        initial_svstate = copy(self.test.svstate)
+        if isinstance(initial_svstate, int):
+            initial_svstate = SVP64State(initial_svstate)
+        yield self.svstate_i.eq(initial_svstate.value)
+        yield self.issuer.svstate_i.ok.eq(1)
+        yield
 
-            # get each test, completely reset the core, and run it
+        print("instructions", instructions)
 
-            for test in self.test_data:
+        # run the loop of the instructions on the current test
+        index = (yield self.issuer.cur_state.pc) // 4
+        while index < len(instructions):
+            ins, code = instructions[index]
 
-                # set up bigendian (TODO: don't do this, use MSR)
-                yield issuer.core_bigendian_i.eq(bigendian)
-                yield Settle()
+            print("hdl instr: 0x{:X}".format(ins & 0xffffffff))
+            print(index, code)
 
+            if counter == 0:
+                # start the core
                 yield
+                yield from set_dmi(dmi, DBGCore.CTRL,
+                                1<<DBGCtrl.START)
+                yield self.issuer.pc_i.ok.eq(0) # no change PC after this
+                yield self.issuer.svstate_i.ok.eq(0) # ditto
                 yield
                 yield
+
+            counter = counter + 1
+
+            # wait until executed
+            while not (yield self.issuer.insn_done):
                 yield
 
-                print(test.name)
-                program = test.program
-                with self.subTest(test.name):
-                    print("regs", test.regs)
-                    print("sprs", test.sprs)
-                    print("cr", test.cr)
-                    print("mem", test.mem)
-                    print("msr", test.msr)
-                    print("assem", program.assembly)
-                    gen = list(program.generate_instructions())
-                    insncode = program.assembly.splitlines()
-                    instructions = list(zip(gen, insncode))
-
-                    # set up the Simulator (which must track TestIssuer exactly)
-                    sim = ISA(simdec2, test.regs, test.sprs, test.cr, test.mem,
-                              test.msr,
-                              initial_insns=gen, respect_pc=True,
-                              disassembly=insncode,
-                              bigendian=bigendian,
-                              initial_svstate=test.svstate)
-
-                    # establish the TestIssuer context (mem, regs etc)
-
-                    pc = 0  # start address
-                    counter = 0  # test to pause/start
-
-                    yield from setup_i_memory(imem, pc, instructions)
-                    yield from setup_tst_memory(l0, sim)
-                    yield from setup_regs(pdecode2, core, test)
-
-                    # set PC and SVSTATE
-                    yield pc_i.eq(pc)
-                    yield issuer.pc_i.ok.eq(1)
-
-                    initial_svstate = test.svstate
-                    if isinstance(initial_svstate, int):
-                        initial_svstate = SVP64State(initial_svstate)
-                    yield svstate_i.eq(initial_svstate.value)
-                    yield issuer.svstate_i.ok.eq(1)
-                    yield
-
-                    print("instructions", instructions)
-
-                    # run the loop of the instructions on the current test
-                    index = sim.pc.CIA.value//4
-                    while index < len(instructions):
-                        ins, code = instructions[index]
-
-                        print("instruction: 0x{:X}".format(ins & 0xffffffff))
-                        print(index, code)
-
-                        if counter == 0:
-                            # start the core
-                            yield
-                            yield from set_dmi(dmi, DBGCore.CTRL,
-                                               1<<DBGCtrl.START)
-                            yield issuer.pc_i.ok.eq(0) # no change PC after this
-                            yield issuer.svstate_i.ok.eq(0) # ditto
-                            yield
-                            yield
-
-                        counter = counter + 1
-
-                        # wait until executed
-                        while not (yield issuer.insn_done):
-                            yield
-
-                        # set up simulated instruction (in simdec2)
-                        try:
-                            yield from sim.setup_one()
-                        except KeyError:  # instruction not in imem: stop
-                            break
-                        yield Settle()
-
-                        # call simulated operation
-                        print("sim", code)
-                        yield from sim.execute_one()
-                        yield Settle()
-                        index = sim.pc.CIA.value//4
-
-                        terminated = yield issuer.dbg.terminated_o
-                        print("terminated", terminated)
-
-                        if index >= len(instructions):
-                            print ("index over, send dmi stop")
-                            # stop at end
-                            yield from set_dmi(dmi, DBGCore.CTRL,
-                                               1<<DBGCtrl.STOP)
-                            yield
-                            yield
-
-                        # register check
-                        yield from check_regs(self, sim, core, test, code)
-
-                        # Memory check
-                        yield from check_sim_memory(self, l0, sim, code)
-
-                        terminated = yield issuer.dbg.terminated_o
-                        print("terminated(2)", terminated)
-                        if terminated:
-                            break
+            yield Settle()
+
+            index = (yield self.issuer.cur_state.pc) // 4
+
+            terminated = yield self.issuer.dbg.terminated_o
+            print("terminated", terminated)
+
+            if index < len(instructions):
+                # Get HDL mem and state
+                state = yield from TestState("hdl", core, self.dut,
+                                            code)
+                hdl_states.append(state)
 
+            if index >= len(instructions):
+                print ("index over, send dmi stop")
                 # stop at end
-                yield from set_dmi(dmi, DBGCore.CTRL, 1<<DBGCtrl.STOP)
+                yield from set_dmi(dmi, DBGCore.CTRL,
+                                1<<DBGCtrl.STOP)
                 yield
                 yield
 
-                # TODO, here is where the static (expected) results
-                # can be checked: register check (TODO, memory check)
-                # see https://bugs.libre-soc.org/show_bug.cgi?id=686#c51
-                # yield from check_regs(self, sim, core, test, code,
-                #                       >>>expected_data<<<)
+            terminated = yield self.issuer.dbg.terminated_o
+            print("terminated(2)", terminated)
+            if terminated:
+                break
 
-                # get CR
-                cr = yield from get_dmi(dmi, DBGCore.CR)
-                print("after test %s cr value %x" % (test.name, cr))
+        return hdl_states
 
-                # get XER
-                xer = yield from get_dmi(dmi, DBGCore.XER)
-                print("after test %s XER value %x" % (test.name, xer))
+    def end_test(self):
+        yield from set_dmi(self.dmi, DBGCore.CTRL, 1<<DBGCtrl.STOP)
+        yield
+        yield
 
-                # test of dmi reg get
-                for int_reg in range(32):
-                    yield from set_dmi(dmi, DBGCore.GSPR_IDX, int_reg)
-                    value = yield from get_dmi(dmi, DBGCore.GSPR_DATA)
+        # TODO, here is where the static (expected) results
+        # can be checked: register check (TODO, memory check)
+        # see https://bugs.libre-soc.org/show_bug.cgi?id=686#c51
+        # yield from check_regs(self, sim, core, test, code,
+        #                       >>>expected_data<<<)
 
-                    print("after test %s reg %2d value %x" %
-                          (test.name, int_reg, value))
+        # get CR
+        cr = yield from get_dmi(self.dmi, DBGCore.CR)
+        print("after test %s cr value %x" % (self.test.name, cr))
 
-                # pull a reset
-                yield from set_dmi(dmi, DBGCore.CTRL, 1<<DBGCtrl.RESET)
-                yield
+        # get XER
+        xer = yield from get_dmi(self.dmi, DBGCore.XER)
+        print("after test %s XER value %x" % (self.test.name, xer))
+
+        # test of dmi reg get
+        for int_reg in range(32):
+            yield from set_dmi(self.dmi, DBGCore.GSPR_IDX, int_reg)
+            value = yield from get_dmi(self.dmi, DBGCore.GSPR_DATA)
+
+            print("after test %s reg %2d value %x" %
+            (self.test.name, int_reg, value))
+
+        # pull a reset
+        yield from set_dmi(self.dmi, DBGCore.CTRL, 1<<DBGCtrl.RESET)
+        yield
+
+
+class TestRunner(TestRunnerBase):
+    def __init__(self, tst_data, microwatt_mmu=False, rom=None,
+                        svp64=True, run_hdl=True, run_sim=True):
+        if run_hdl:
+            run_hdl = HDLRunner
+        super().__init__(tst_data, microwatt_mmu=microwatt_mmu,
+                        rom=rom,
+                        svp64=svp64, run_hdl=run_hdl, run_sim=run_sim)
 
-        styles = {
-            'dec': {'base': 'dec'},
-            'bin': {'base': 'bin'},
-            'closed': {'closed': True}
-        }
-
-        traces = [
-            'clk',
-            ('state machines', 'closed', [
-                'fetch_pc_i_valid', 'fetch_pc_o_ready',
-                'fetch_fsm_state',
-                'fetch_insn_o_valid', 'fetch_insn_i_ready',
-                'pred_insn_i_valid', 'pred_insn_o_ready',
-                'fetch_predicate_state',
-                'pred_mask_o_valid', 'pred_mask_i_ready',
-                'issue_fsm_state',
-                'exec_insn_i_valid', 'exec_insn_o_ready',
-                'exec_fsm_state',
-                'exec_pc_o_valid', 'exec_pc_i_ready',
-                'insn_done', 'core_stop_o', 'pc_i_ok', 'pc_changed',
-                'is_last', 'dec2.no_out_vec']),
-            {'comment': 'fetch and decode'},
-            (None, 'dec', [
-                'cia[63:0]', 'nia[63:0]', 'pc[63:0]',
-                'cur_pc[63:0]', 'core_core_cia[63:0]']),
-            'raw_insn_i[31:0]',
-            'raw_opcode_in[31:0]', 'insn_type', 'dec2.dec2_exc_happened',
-            ('svp64 decoding', 'closed', [
-                'svp64_rm[23:0]', ('dec2.extra[8:0]', 'bin'),
-                'dec2.sv_rm_dec.mode', 'dec2.sv_rm_dec.predmode',
-                'dec2.sv_rm_dec.ptype_in',
-                'dec2.sv_rm_dec.dstpred[2:0]', 'dec2.sv_rm_dec.srcpred[2:0]',
-                'dstmask[63:0]', 'srcmask[63:0]',
-                'dregread[4:0]', 'dinvert',
-                'sregread[4:0]', 'sinvert',
-                'core.int.pred__addr[4:0]', 'core.int.pred__data_o[63:0]',
-                'core.int.pred__ren']),
-            ('register augmentation', 'dec', 'closed', [
-                {'comment': 'v3.0b registers'},
-                'dec2.dec_o.RT[4:0]',
-                'dec2.dec_a.RA[4:0]',
-                'dec2.dec_b.RB[4:0]',
-                ('Rdest', [
-                    'dec2.o_svdec.reg_in[4:0]',
-                    ('dec2.o_svdec.spec[2:0]', 'bin'),
-                    'dec2.o_svdec.reg_out[6:0]']),
-                ('Rsrc1', [
-                    'dec2.in1_svdec.reg_in[4:0]',
-                    ('dec2.in1_svdec.spec[2:0]', 'bin'),
-                    'dec2.in1_svdec.reg_out[6:0]']),
-                ('Rsrc1', [
-                    'dec2.in2_svdec.reg_in[4:0]',
-                    ('dec2.in2_svdec.spec[2:0]', 'bin'),
-                    'dec2.in2_svdec.reg_out[6:0]']),
-                {'comment': 'SVP64 registers'},
-                'dec2.rego[6:0]', 'dec2.reg1[6:0]', 'dec2.reg2[6:0]'
-            ]),
-            {'comment': 'svp64 context'},
-            'core_core_vl[6:0]', 'core_core_maxvl[6:0]',
-            'core_core_srcstep[6:0]', 'next_srcstep[6:0]',
-            'core_core_dststep[6:0]',
-            {'comment': 'issue and execute'},
-            'core.core_core_insn_type',
-            (None, 'dec', [
-                'core_rego[6:0]', 'core_reg1[6:0]', 'core_reg2[6:0]']),
-            'issue_i', 'busy_o',
-            {'comment': 'dmi'},
-            'dbg.dmi_req_i', 'dbg.dmi_ack_o',
-            {'comment': 'instruction memory'},
-            'imem.sram.rdport.memory(0)[63:0]',
-            {'comment': 'registers'},
-            # match with soc.regfile.regfiles.IntRegs port names
-            'core.int.rp_src1.memory(0)[63:0]',
-            'core.int.rp_src1.memory(1)[63:0]',
-            'core.int.rp_src1.memory(2)[63:0]',
-            'core.int.rp_src1.memory(3)[63:0]',
-            'core.int.rp_src1.memory(4)[63:0]',
-            'core.int.rp_src1.memory(5)[63:0]',
-            'core.int.rp_src1.memory(6)[63:0]',
-            'core.int.rp_src1.memory(7)[63:0]',
-            'core.int.rp_src1.memory(9)[63:0]',
-            'core.int.rp_src1.memory(10)[63:0]',
-            'core.int.rp_src1.memory(13)[63:0]'
-        ]
-
-        # PortInterface module path varies depending on MMU option
-        if self.microwatt_mmu:
-            pi_module = 'core.ldst0'
-        else:
-            pi_module = 'core.fus.ldst0'
-
-        traces += [('ld/st port interface', {'submodule': pi_module}, [
-            'oper_r__insn_type',
-            'ldst_port0_is_ld_i',
-            'ldst_port0_is_st_i',
-            'ldst_port0_busy_o',
-            'ldst_port0_addr_i[47:0]',
-            'ldst_port0_addr_i_ok',
-            'ldst_port0_addr_ok_o',
-            'ldst_port0_exc_happened',
-            'ldst_port0_st_data_i[63:0]',
-            'ldst_port0_st_data_i_ok',
-            'ldst_port0_ld_data_o[63:0]',
-            'ldst_port0_ld_data_o_ok',
-            'exc_o_happened',
-            'cancel'
-        ])]
-
-        if self.microwatt_mmu:
-            traces += [
-                {'comment': 'microwatt_mmu'},
-                'core.fus.mmu0.alu_mmu0.illegal',
-                'core.fus.mmu0.alu_mmu0.debug0[3:0]',
-                'core.fus.mmu0.alu_mmu0.mmu.state',
-                'core.fus.mmu0.alu_mmu0.mmu.pid[31:0]',
-                'core.fus.mmu0.alu_mmu0.mmu.prtbl[63:0]',
-                {'comment': 'wishbone_memory'},
-                'core.fus.mmu0.alu_mmu0.dcache.stb',
-                'core.fus.mmu0.alu_mmu0.dcache.cyc',
-                'core.fus.mmu0.alu_mmu0.dcache.we',
-                'core.fus.mmu0.alu_mmu0.dcache.ack',
-                'core.fus.mmu0.alu_mmu0.dcache.stall,'
-            ]
-
-        write_gtkw("issuer_simulator.gtkw",
-                   "issuer_simulator.vcd",
-                   traces, styles, module='top.issuer')
-
-        # add run of instructions
-        sim.add_sync_process(process)
-
-        # optionally, if a wishbone-based ROM is passed in, run that as an
-        # extra emulated process
-        if self.rom is not None:
-            dcache = core.fus.fus["mmu0"].alu.dcache
-            default_mem = self.rom
-            sim.add_sync_process(wrap(wb_get(dcache, default_mem, "DCACHE")))
-
-        with sim.write_vcd("issuer_simulator.vcd"):
-            sim.run()
index 37a2ebb914d01dd586dd80a82d184f52d29f770b..d2f4b51ff74b865c0e758c34e49db1f92f094634 100644 (file)
@@ -12,6 +12,9 @@ from openpower.test.state import (State, state_add, state_factory,
 from soc.fu.compunits.test.test_compunit import get_l0_mem
 
 class HDLState(State):
+    """HDLState: Obtains registers and memory from an nmigen simulator
+    object by implementing State class methods.
+    """
     def __init__(self, core):
         super().__init__()
         self.core = core
@@ -52,10 +55,10 @@ class HDLState(State):
     def get_mem(self):
         # get the underlying HDL-simulated memory from the L0CacheBuffer
         hdlmem = get_l0_mem(self.core.l0)
-        self.mem = []
+        self.mem = {}
         for i in range(hdlmem.depth):
             value = yield hdlmem._array[i] # should not really do this
-            self.mem.append(((i*8), value))
+            self.mem[i*8] = value
 
 
 # add to State Factory