Compare commits
6 Commits
f61328dac4
...
77b772c7ee
Author | SHA1 | Date |
---|---|---|
David Anderson | 77b772c7ee | |
David Anderson | 25d1806590 | |
David Anderson | 5e997201db | |
David Anderson | 6fd040565c | |
David Anderson | 0005ad6fe5 | |
David Anderson | d960eee973 |
|
@ -20,11 +20,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1723175592,
|
"lastModified": 1725432240,
|
||||||
"narHash": "sha256-M0xJ3FbDUc4fRZ84dPGx5VvgFsOzds77KiBMW/mMTnI=",
|
"narHash": "sha256-+yj+xgsfZaErbfYM3T+QvEE2hU7UuE+Jf0fJCJ8uPS0=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "5e0ca22929f3342b19569b21b2f3462f053e497b",
|
"rev": "ad416d066ca1222956472ab7d0555a6946746a80",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package PLL;
|
package PLL;
|
||||||
|
|
||||||
// Frequencies: FPGA 100MHz, CPU 10MHz, VGA 25MHz
|
// Frequencies: FPGA 100MHz, CPU 8MHz, VGA 25MHz
|
||||||
//
|
//
|
||||||
// To regenerate, see 'inv genclk -h'
|
// To regenerate, see 'inv genclk -h'
|
||||||
|
|
|
@ -6,13 +6,13 @@ module PLL
|
||||||
(
|
(
|
||||||
input CLK_REF, // 25 MHz, 0 deg
|
input CLK_REF, // 25 MHz, 0 deg
|
||||||
output CLK_MAIN, // 100 MHz, 0 deg
|
output CLK_MAIN, // 100 MHz, 0 deg
|
||||||
output CLK_CPU, // 10 MHz, 0 deg
|
output CLK_CPU, // 8 MHz, 0 deg
|
||||||
output CLK_VGA, // 25 MHz, 0 deg
|
output CLK_VGA, // 25 MHz, 0 deg
|
||||||
output locked
|
output locked
|
||||||
);
|
);
|
||||||
(* FREQUENCY_PIN_CLKI="25" *)
|
(* FREQUENCY_PIN_CLKI="25" *)
|
||||||
(* FREQUENCY_PIN_CLKOP="100" *)
|
(* FREQUENCY_PIN_CLKOP="100" *)
|
||||||
(* FREQUENCY_PIN_CLKOS="10" *)
|
(* FREQUENCY_PIN_CLKOS="8" *)
|
||||||
(* FREQUENCY_PIN_CLKOS2="25" *)
|
(* FREQUENCY_PIN_CLKOS2="25" *)
|
||||||
(* ICP_CURRENT="12" *) (* LPF_RESISTOR="8" *) (* MFG_ENABLE_FILTEROPAMP="1" *) (* MFG_GMCREF_SEL="2" *)
|
(* ICP_CURRENT="12" *) (* LPF_RESISTOR="8" *) (* MFG_ENABLE_FILTEROPAMP="1" *) (* MFG_GMCREF_SEL="2" *)
|
||||||
EHXPLLL #(
|
EHXPLLL #(
|
||||||
|
@ -30,7 +30,7 @@ EHXPLLL #(
|
||||||
.CLKOP_CPHASE(2),
|
.CLKOP_CPHASE(2),
|
||||||
.CLKOP_FPHASE(0),
|
.CLKOP_FPHASE(0),
|
||||||
.CLKOS_ENABLE("ENABLED"),
|
.CLKOS_ENABLE("ENABLED"),
|
||||||
.CLKOS_DIV(60),
|
.CLKOS_DIV(75),
|
||||||
.CLKOS_CPHASE(2),
|
.CLKOS_CPHASE(2),
|
||||||
.CLKOS_FPHASE(0),
|
.CLKOS_FPHASE(0),
|
||||||
.CLKOS2_ENABLE("ENABLED"),
|
.CLKOS2_ENABLE("ENABLED"),
|
|
@ -0,0 +1,57 @@
|
||||||
|
package Top;
|
||||||
|
|
||||||
|
import Connectable::*;
|
||||||
|
import TriState::*;
|
||||||
|
|
||||||
|
import ClockOut::*;
|
||||||
|
import PLL::*;
|
||||||
|
|
||||||
|
interface SystemBus;
|
||||||
|
(* always_enabled,prefix="" *)
|
||||||
|
method Action addr(UInt#(24) addr);
|
||||||
|
(* always_enabled,prefix="" *)
|
||||||
|
method Action phi2(bit phi2);
|
||||||
|
(* always_enabled,prefix="" *)
|
||||||
|
method Action write(bit we);
|
||||||
|
endinterface
|
||||||
|
|
||||||
|
module mkSystemBus(SystemBus);
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
interface Top;
|
||||||
|
(* always_ready *)
|
||||||
|
method bit clkout();
|
||||||
|
|
||||||
|
interface SystemBus cpu;
|
||||||
|
endinterface
|
||||||
|
|
||||||
|
(* synthesize,no_default_clock,no_default_reset,default_gate_unused *)
|
||||||
|
module mkTop(Clock clk_ref,
|
||||||
|
(* clocked_by="no_clock" *) Reset rst,
|
||||||
|
(* clocked_by="no_clock" *) Inout#(Bit#(8)) data,
|
||||||
|
Top ifc);
|
||||||
|
let pll <- mkPLL(clk_ref);
|
||||||
|
let cpu_clk <- mkClockOut(clocked_by(pll.cpu_clk), reset_by(rst));
|
||||||
|
|
||||||
|
Reg#(Bool) data_out_en <- mkReg(False, clocked_by(pll.cpu_clk), reset_by(rst));
|
||||||
|
Reg#(Bit#(8)) data_out <- mkReg(0, clocked_by(pll.cpu_clk), reset_by(rst));
|
||||||
|
TriState#(Bit#(8)) data_in <- mkTriState(data_out_en, data_out, clocked_by(pll.cpu_clk), reset_by(rst));
|
||||||
|
mkConnection(data, data_in.io);
|
||||||
|
|
||||||
|
interface SystemBus cpu;
|
||||||
|
method clkout = cpu_clk.value;
|
||||||
|
method Action addr(a);
|
||||||
|
noAction;
|
||||||
|
endmethod
|
||||||
|
method Action phi2(v);
|
||||||
|
noAction;
|
||||||
|
endmethod
|
||||||
|
method Action write(bit we);
|
||||||
|
noAction;
|
||||||
|
endmethod
|
||||||
|
//interface data = data_in.io;
|
||||||
|
endinterface
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
endpackage
|
|
@ -0,0 +1,16 @@
|
||||||
|
package ClockOut;
|
||||||
|
|
||||||
|
interface ClockOut;
|
||||||
|
method bit value();
|
||||||
|
endinterface
|
||||||
|
|
||||||
|
import "BVI" ClockOut =
|
||||||
|
module mkClockOut(ClockOut);
|
||||||
|
default_reset no_reset;
|
||||||
|
default_clock clk (CLK, (* unused *)GATE);
|
||||||
|
|
||||||
|
method CLK_BIT value() clocked_by(no_clock);
|
||||||
|
|
||||||
|
schedule value CF value;
|
||||||
|
endmodule
|
||||||
|
endpackage
|
|
@ -0,0 +1,3 @@
|
||||||
|
module ClockOut(input CLK, output CLK_BIT);
|
||||||
|
assign CLK_BIT = CLK;
|
||||||
|
endmodule
|
|
@ -0,0 +1,96 @@
|
||||||
|
#!/usr/bin/env perl
|
||||||
|
# -*-Perl-*-
|
||||||
|
################################################################################
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
### NOTE ###
|
||||||
|
#
|
||||||
|
# This script comes from the Bluespec source repository,
|
||||||
|
# https://github.com/B-Lang-org/bsc/blob/main/util/scripts/basicinout.pl
|
||||||
|
#
|
||||||
|
# Unlike the rest of this repo, it is licensed under BSD-3-Clause like
|
||||||
|
# the original, with credit and gratitude to Bluespec Inc. and the
|
||||||
|
# anonymous programmers who wrote it prior to the open-sourcing of
|
||||||
|
# Bluespec.
|
||||||
|
#
|
||||||
|
### NOTE ###
|
||||||
|
|
||||||
|
my %RENAME_PORTS = ();
|
||||||
|
my %SIGNALS = ();
|
||||||
|
my %PINS = ();
|
||||||
|
|
||||||
|
|
||||||
|
foreach my $outfile (@ARGV) {
|
||||||
|
# read the file
|
||||||
|
next unless open(FILE, $outfile);
|
||||||
|
my @lines = <FILE>;
|
||||||
|
close(FILE);
|
||||||
|
|
||||||
|
# Locate inout signals
|
||||||
|
my $inmodule = 0;
|
||||||
|
my $showedassigns = 0;
|
||||||
|
my @newlines;
|
||||||
|
foreach my $line (@lines) {
|
||||||
|
if ($line =~ m/rename\:\s+(\S+)\=(\S+)/) {
|
||||||
|
$RENAME_PORTS{$1} = $2;
|
||||||
|
} elsif ($line =~ m/^\s*module\s*[a-zA-Z0-9_\$]+\s*\(\s*\.(\S+)\(([a-zA-Z0-9_\$]+)\)/) {
|
||||||
|
$inmodule = 1;
|
||||||
|
$SIGNALS{$2} = $1;
|
||||||
|
$PINS{$1} = $2;
|
||||||
|
$line =~ s/\.(\S+)\(([a-zA-Z0-9_\$]+)\)/$1/;
|
||||||
|
push @newlines, $line;
|
||||||
|
} elsif ($line =~ m/^\s*module\s+(\S+)\s*\(/) {
|
||||||
|
$inmodule = 1;
|
||||||
|
push @newlines, $line;
|
||||||
|
} elsif ($line =~ m/^\s*\.(\S+)\(([a-zA-Z0-9_\$]+)\)/ && $inmodule) {
|
||||||
|
$SIGNALS{$2} = $1;
|
||||||
|
$PINS{$1} = $2;
|
||||||
|
$line =~ s/\.(\S+)\(([a-zA-Z0-9_\$]+)\)/$1/;
|
||||||
|
push @newlines, $line;
|
||||||
|
} elsif ($line =~ m/\s*inout(.*?)\s*(\S+)\;/) {
|
||||||
|
my $signal = $2;
|
||||||
|
my $origsig = $2;
|
||||||
|
|
||||||
|
if (exists $SIGNALS{$signal}) {
|
||||||
|
my $pin = $SIGNALS{$signal};
|
||||||
|
$signal =~ s/\$/\\\$/g;
|
||||||
|
$line =~ s/$signal/$pin/;
|
||||||
|
} else {
|
||||||
|
print("Failed to locate signal=$signal in module port list (basicinout)!\nPlease report this error to the BSC developers, by opening a ticket\nin the issue database\: https\:\/\/github.com\/B-Lang-org\/bsc\/issues\n\n");
|
||||||
|
die;
|
||||||
|
}
|
||||||
|
push @newlines, $line;
|
||||||
|
} elsif ($line =~ m/input/ && $inmodule) {
|
||||||
|
$inmodule = 0;
|
||||||
|
push @newlines, $line;
|
||||||
|
} elsif ($line =~ m/\.(\S+)\(([a-zA-Z0-9\$_]+)\)/) {
|
||||||
|
my $signal = $2;
|
||||||
|
if (exists $SIGNALS{$signal}) {
|
||||||
|
my $pin = $SIGNALS{$signal};
|
||||||
|
$signal =~ s/\$/\\\$/g;
|
||||||
|
$line =~ s/$signal/$pin/;
|
||||||
|
}
|
||||||
|
push @newlines, $line;
|
||||||
|
} else {
|
||||||
|
push @newlines, $line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Rename any signals that need renaming
|
||||||
|
my @renamed_lines;
|
||||||
|
foreach my $line (@newlines) {
|
||||||
|
foreach my $signal (keys %RENAME_PORTS) {
|
||||||
|
my $replacement = $RENAME_PORTS{$signal};
|
||||||
|
if ($line =~ m/$signal/) {
|
||||||
|
$line =~ s/([A-Za-z0-9_\$]*$signal)/$replacement/g;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
push @renamed_lines, $line;
|
||||||
|
}
|
||||||
|
|
||||||
|
# write out the new version
|
||||||
|
open(OFILE, ">${outfile}") or die("Could not create output file: $!\n");
|
||||||
|
print OFILE @renamed_lines;
|
||||||
|
close(OFILE);
|
||||||
|
}
|
||||||
|
1;
|
49
tasks.py
49
tasks.py
|
@ -24,18 +24,45 @@ def bsc_root(c):
|
||||||
return Path(l[len(dir_prefix):])
|
return Path(l[len(dir_prefix):])
|
||||||
raise RuntimeError("Couldn't locate Bluespec root dir")
|
raise RuntimeError("Couldn't locate Bluespec root dir")
|
||||||
|
|
||||||
def find_verilog_modules(c, modules):
|
def bluespec_libdirs(*extras):
|
||||||
libpaths = [Path("lib"), bsc_root(c) / "Verilog"]
|
ret = []
|
||||||
|
for x in extras:
|
||||||
|
x = Path(x)
|
||||||
|
if not x.is_dir():
|
||||||
|
x = x.parent
|
||||||
|
if not x.is_dir():
|
||||||
|
raise ValueError(f"unknown libdir thing {x}")
|
||||||
|
ret.append(x)
|
||||||
|
|
||||||
|
bsv_dirs = list(sorted(set(p.parent for p in Path("").glob("**/*.bsv"))))
|
||||||
|
exclude_trees = [Path("hardware"), Path("experiments"), Path("sim")] + ret
|
||||||
|
for d in bsv_dirs:
|
||||||
|
if any(d.is_relative_to(x) for x in exclude_trees):
|
||||||
|
continue
|
||||||
|
ret.append(d)
|
||||||
|
ret.append("%/Libraries")
|
||||||
|
return ":".join(str(s) for s in ret)
|
||||||
|
|
||||||
|
def find_verilog_modules(c, target_dir, modules):
|
||||||
|
preferred_libpaths = [target_dir, Path("lib"), bsc_root(c) / "Verilog"]
|
||||||
ret = []
|
ret = []
|
||||||
for module in modules:
|
for module in modules:
|
||||||
module_path = None
|
module_path = None
|
||||||
|
verilog_path = Path(module).with_suffix(".v")
|
||||||
|
# Try preferred libpaths first.
|
||||||
for p in libpaths:
|
for p in libpaths:
|
||||||
f = p / Path(module).with_suffix(".v")
|
f = p / verilog_path
|
||||||
if f.is_file():
|
if f.is_file():
|
||||||
module_path = f
|
module_path = f
|
||||||
break
|
break
|
||||||
if module_path is None:
|
if module_path is None:
|
||||||
raise RuntimeError(f"Cannot find verilog module {module} in {libpaths}")
|
# Not in preferred paths, accept anywhere now.
|
||||||
|
matches = Path("").glob(f"**/{module}.v")
|
||||||
|
if len(matches) > 1:
|
||||||
|
raise RuntimeError(f"Multiple candidates for verilog module {module}: {matches}")
|
||||||
|
elif len(matches) == 0:
|
||||||
|
raise RuntimeError(f"Cannot find verilog module {module} in {libpaths}")
|
||||||
|
module_path = matches[0]
|
||||||
ret.append(module_path)
|
ret.append(module_path)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
@ -82,14 +109,16 @@ def phase(name):
|
||||||
print("")
|
print("")
|
||||||
|
|
||||||
@task
|
@task
|
||||||
def build(c, target="."):
|
def build(c, target):
|
||||||
phase("Compile Bluespec")
|
phase("Compile Bluespec")
|
||||||
|
|
||||||
verilog_files = []
|
verilog_files = []
|
||||||
for target in expand_build_target(target):
|
for target in expand_build_target(target):
|
||||||
out_info, out_verilog, out_bsc = ensure_build_dirs(target, "info", "verilog", "bsc")
|
out_info, out_verilog, out_bsc = ensure_build_dirs(target, "info", "verilog", "bsc")
|
||||||
|
libdirs = bluespec_libdirs(target)
|
||||||
print(f"Building {target}")
|
print(f"Building {target}")
|
||||||
c.run(f"bsc -aggressive-conditions -check-assert -remove-dollar -remove-empty-rules -remove-false-rules -remove-starved-rules -remove-unused-modules -show-method-conf -show-method-bvi -u -verilog -info-dir {out_info} -vdir {out_verilog} -bdir {out_bsc} -p {target.parent}:vram:lib:%/Libraries -show-module-use -show-compiles {target}")
|
print(f"Libdirs: {libdirs.replace(':', ', ')}")
|
||||||
|
c.run(f"bsc -aggressive-conditions -check-assert -remove-dollar -remove-empty-rules -remove-false-rules -remove-starved-rules -verilog-filter scripts/basicinout.pl -show-method-conf -show-method-bvi -u -verilog -info-dir {out_info} -vdir {out_verilog} -bdir {out_bsc} -p {libdirs} -show-module-use -show-compiles {target}")
|
||||||
|
|
||||||
module_name = Path(f"mk{target.stem}")
|
module_name = Path(f"mk{target.stem}")
|
||||||
verilog_main_file = out_verilog / module_name.with_suffix(".v")
|
verilog_main_file = out_verilog / module_name.with_suffix(".v")
|
||||||
|
@ -98,7 +127,7 @@ def build(c, target="."):
|
||||||
use_file = out_verilog / module_name.with_suffix(".use")
|
use_file = out_verilog / module_name.with_suffix(".use")
|
||||||
if use_file.is_file():
|
if use_file.is_file():
|
||||||
with open(out_verilog / module_name.with_suffix(".use")) as f:
|
with open(out_verilog / module_name.with_suffix(".use")) as f:
|
||||||
verilog_files.extend(find_verilog_modules(c, f.read().splitlines()))
|
verilog_files.extend(find_verilog_modules(c, target.parent, f.read().splitlines()))
|
||||||
|
|
||||||
if verilog_files:
|
if verilog_files:
|
||||||
print("\nVerilog files for synthesis:")
|
print("\nVerilog files for synthesis:")
|
||||||
|
@ -187,7 +216,9 @@ def synth(c, target):
|
||||||
def test(c, target):
|
def test(c, target):
|
||||||
for target in expand_test_target(target):
|
for target in expand_test_target(target):
|
||||||
out_info, out_sim, out_bsc = ensure_build_dirs(target, "info", "sim", "bsc")
|
out_info, out_sim, out_bsc = ensure_build_dirs(target, "info", "sim", "bsc")
|
||||||
c.run(f"bsc -show-schedule -aggressive-conditions -check-assert -u -sim -info-dir {out_info} -simdir {out_sim} -bdir {out_bsc} -g mkTB -p {target.parent}:lib:sim:%/Libraries {target}")
|
libdirs = bluespec_libdirs(target, "sim")
|
||||||
|
print(f"Libdirs: {libdirs.replace(':', ', ')}")
|
||||||
|
c.run(f"bsc -show-schedule -aggressive-conditions -check-assert -u -sim -info-dir {out_info} -simdir {out_sim} -bdir {out_bsc} -g mkTB -p {libdirs} {target}")
|
||||||
exec = out_sim / "TB"
|
exec = out_sim / "TB"
|
||||||
c.run(f"bsc -p {out_bsc} -sim -simdir {out_sim} -e mkTB -o {exec}")
|
c.run(f"bsc -p {out_bsc} -sim -simdir {out_sim} -e mkTB -o {exec}")
|
||||||
testdata = out_sim / "testdata"
|
testdata = out_sim / "testdata"
|
||||||
|
@ -205,7 +236,7 @@ def clean(c):
|
||||||
|
|
||||||
@task
|
@task
|
||||||
def genclk(c, in_mhz=25, main_mhz=100, cpu_mhz=10, vga_mhz=25):
|
def genclk(c, in_mhz=25, main_mhz=100, cpu_mhz=10, vga_mhz=25):
|
||||||
out = Path("gary/PLL.v")
|
out = Path("sentinel65x/PLL.v")
|
||||||
c.run(f"ecppll -f {out} --module PLL --clkin_name CLK_REF --clkin {in_mhz} --clkout0_name CLK_MAIN --clkout0 {main_mhz} --clkout1_name CLK_CPU --clkout1 {cpu_mhz} --clkout2_name CLK_VGA --clkout2 {vga_mhz}")
|
c.run(f"ecppll -f {out} --module PLL --clkin_name CLK_REF --clkin {in_mhz} --clkout0_name CLK_MAIN --clkout0 {main_mhz} --clkout1_name CLK_CPU --clkout1 {cpu_mhz} --clkout2_name CLK_VGA --clkout2 {vga_mhz}")
|
||||||
bsv_out = out.with_suffix(".bsv")
|
bsv_out = out.with_suffix(".bsv")
|
||||||
with open(bsv_out) as f:
|
with open(bsv_out) as f:
|
||||||
|
|
Loading…
Reference in New Issue