Compare commits
No commits in common. "8937e27d18231c1cd2c771b88007704ebce1f96b" and "8ab867d2d211d0ba44268ac447d435abf30f7673" have entirely different histories.
8937e27d18
...
8ab867d2d2
|
@ -1,47 +0,0 @@
|
||||||
package Top;
|
|
||||||
|
|
||||||
import Connectable::*;
|
|
||||||
import GetPut::*;
|
|
||||||
import ClientServer::*;
|
|
||||||
|
|
||||||
import PackUnpack::*;
|
|
||||||
import UART::*;
|
|
||||||
import VRAM::*;
|
|
||||||
|
|
||||||
module mkUARTDebugger(Integer clock_frequency, Integer uart_bitrate, VRAMServer mem, UART_PHY ifc);
|
|
||||||
UART _uart <- mkUART(clock_frequency, uart_bitrate);
|
|
||||||
disableFlowControl(_uart); // Can't do hardware flow control on ULX3S
|
|
||||||
|
|
||||||
Server#(Bit#(8), VRAMRequest) _decode <- mkUnpacker();
|
|
||||||
Server#(VRAMResponse, Bit#(8)) _encode <- mkPacker();
|
|
||||||
|
|
||||||
mkConnection(_uart.receive, _decode.request);
|
|
||||||
mkConnection(_decode.response, mem.request);
|
|
||||||
mkConnection(mem.response, _encode.request);
|
|
||||||
mkConnection(_encode.response, _uart.send);
|
|
||||||
|
|
||||||
return _uart.phy;
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
interface Top;
|
|
||||||
(* always_enabled,prefix="debug" *)
|
|
||||||
method Action debugger_rx_in((* port="serial_in" *) bit b);
|
|
||||||
(* always_ready,result="debug_serial_out" *)
|
|
||||||
method bit debugger_tx_out();
|
|
||||||
endinterface
|
|
||||||
|
|
||||||
(* synthesize *)
|
|
||||||
module mkTop(Top);
|
|
||||||
////////////
|
|
||||||
// Memory
|
|
||||||
VRAM mem <- mkVRAM(128);
|
|
||||||
|
|
||||||
////////////
|
|
||||||
// Debug interface
|
|
||||||
let debugger <- mkUARTDebugger(25_000_000, 115_200, mem.debugger);
|
|
||||||
|
|
||||||
method debugger_rx_in = debugger.rx_in;
|
|
||||||
method debugger_tx_out = debugger.tx_out;
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
endpackage
|
|
|
@ -1,16 +0,0 @@
|
||||||
BLOCK RESETPATHS;
|
|
||||||
BLOCK ASYNCPATHS;
|
|
||||||
|
|
||||||
SYSCONFIG CONFIG_IOVOLTAGE=3.3 COMPRESS_CONFIG=ON MCCLK_FREQ=62 SLAVE_SPI_PORT=DISABLE MASTER_SPI_PORT=ENABLE SLAVE_PARALLEL_PORT=DISABLE;
|
|
||||||
|
|
||||||
LOCATE COMP "CLK" SITE "G2";
|
|
||||||
IOBUF PORT "CLK" PULLMODE=NONE IO_TYPE=LVCMOS33;
|
|
||||||
FREQUENCY PORT "CLK" 25 MHZ;
|
|
||||||
|
|
||||||
LOCATE COMP "RST_N" SITE "D6"; # BTN_PWRn (inverted logic)
|
|
||||||
IOBUF PORT "RST_N" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
|
||||||
|
|
||||||
LOCATE COMP "debug_serial_out" SITE "L4"; # FPGA transmits to ftdi
|
|
||||||
LOCATE COMP "debug_serial_in" SITE "M1"; # FPGA receives from ftdi
|
|
||||||
IOBUF PORT "debug_serial_out" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
|
||||||
IOBUF PORT "debug_serial_in" PULLMODE=UP IO_TYPE=LVCMOS33;
|
|
|
@ -1,77 +0,0 @@
|
||||||
package PackUnpack;
|
|
||||||
|
|
||||||
import Vector::*;
|
|
||||||
import FIFOF::*;
|
|
||||||
import SpecialFIFOs::*;
|
|
||||||
import GetPut::*;
|
|
||||||
import ClientServer::*;
|
|
||||||
|
|
||||||
// mkPacker makes a server that converts data_in values into one or
|
|
||||||
// more data_out values, both of which must be in the Bits
|
|
||||||
// typeclass. The packing is implemented by taking the bit
|
|
||||||
// representation of data_in and striping it across as many data_outs
|
|
||||||
// as needed to preserve all the bytes. If data_in is not an exact
|
|
||||||
// multiple of data_out, the final data_out is padded with zeros.
|
|
||||||
module mkPacker(Server#(data_in, data_out))
|
|
||||||
provisos(Bits#(data_in, data_in_bits),
|
|
||||||
Bits#(data_out, data_out_bits),
|
|
||||||
Div#(data_in_bits, data_out_bits, data_out_elts),
|
|
||||||
Min#(data_out_elts, 1, 1),
|
|
||||||
Log#(TAdd#(data_out_elts, 1), data_out_elts_cnt),
|
|
||||||
Add#(data_in_bits, _pad, TMul#(data_out_elts, data_out_bits)));
|
|
||||||
let data_out_elts = valueOf(data_out_elts);
|
|
||||||
|
|
||||||
Reg#(Vector#(data_out_elts, data_out)) vals_out <- mkRegU();
|
|
||||||
Reg#(UInt#(data_out_elts_cnt)) num_vals <- mkReg(0);
|
|
||||||
FIFOF#(data_out) out <- mkBypassFIFOF();
|
|
||||||
|
|
||||||
rule push_out (num_vals > 0);
|
|
||||||
out.enq(vals_out[0]);
|
|
||||||
vals_out <= shiftOutFrom0(unpack(0), vals_out, 1);
|
|
||||||
num_vals <= num_vals-1;
|
|
||||||
endrule
|
|
||||||
|
|
||||||
interface Put request;
|
|
||||||
method Action put(di) if (num_vals == 0);
|
|
||||||
vals_out <= reverse(unpack(extend(pack(di))));
|
|
||||||
num_vals <= fromInteger(data_out_elts);
|
|
||||||
endmethod
|
|
||||||
endinterface
|
|
||||||
interface response = toGet(out);
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
// mkUnpacker makes a server that converts one or more data_in values
|
|
||||||
// into a data_out value. Both data_in and data_out must be in the
|
|
||||||
// Bits typeclass. The unpacking is implemented by concatenating the
|
|
||||||
// bit representation of consecutive data_in values until enough bits
|
|
||||||
// have been accumulated to represent one data_out. If data_out is not
|
|
||||||
// an exact multiple of data_in, the unneeded upper bits of the final
|
|
||||||
// data_in are discarded.
|
|
||||||
module mkUnpacker(Server#(data_in, data_out))
|
|
||||||
provisos(Bits#(data_in, data_in_bits),
|
|
||||||
Bits#(data_out, data_out_bits),
|
|
||||||
Div#(data_out_bits, data_in_bits, data_in_elts),
|
|
||||||
Min#(data_in_elts, 1, 1),
|
|
||||||
Log#(TAdd#(data_in_elts, 1), data_in_elts_cnt),
|
|
||||||
Add#(data_out_bits, _pad, TMul#(data_in_elts, data_in_bits)));
|
|
||||||
|
|
||||||
Reg#(Vector#(data_in_elts, data_in)) vals_in <- mkRegU();
|
|
||||||
Reg#(UInt#(data_in_elts_cnt)) num_vals <- mkReg(0);
|
|
||||||
FIFOF#(data_out) out <- mkBypassFIFOF();
|
|
||||||
|
|
||||||
rule push_out (num_vals == fromInteger(valueOf(data_in_elts)));
|
|
||||||
out.enq(unpack(truncate(pack(vals_in))));
|
|
||||||
num_vals <= 0;
|
|
||||||
endrule
|
|
||||||
|
|
||||||
interface Put request;
|
|
||||||
method Action put(di) if (num_vals < fromInteger(valueOf(data_in_elts)));
|
|
||||||
vals_in <= shiftInAt0(vals_in, di);
|
|
||||||
num_vals <= num_vals+1;
|
|
||||||
endmethod
|
|
||||||
endinterface
|
|
||||||
interface response = toGet(out);
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
endpackage
|
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
package PackUnpack_Test;
|
|
||||||
|
|
||||||
import StmtFSM::*;
|
|
||||||
import Assert::*;
|
|
||||||
import GetPut::*;
|
|
||||||
import ClientServer::*;
|
|
||||||
|
|
||||||
import PackUnpack::*;
|
|
||||||
import Testing::*;
|
|
||||||
|
|
||||||
module mkTB();
|
|
||||||
let testflags <- mkTestFlags();
|
|
||||||
|
|
||||||
Server#(UInt#(17), Bit#(8)) dut_pack <- mkPacker();
|
|
||||||
Server#(Bit#(8), UInt#(17)) dut_unpack <- mkUnpacker();
|
|
||||||
|
|
||||||
function Action put_pack(UInt#(17) v);
|
|
||||||
return action
|
|
||||||
dut_pack.request.put(v);
|
|
||||||
if (testflags.verbose)
|
|
||||||
$display("pack.put(%0d), binary %017b", v, v);
|
|
||||||
endaction;
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function Action check_pack(Bit#(8) want);
|
|
||||||
return action
|
|
||||||
let got <- dut_pack.response.get();
|
|
||||||
if (testflags.verbose)
|
|
||||||
$display("pack.get = %0d (%08b), want %0d (%08b)", got, got, want, want);
|
|
||||||
dynamicAssert(got == want, "got incorrect packed byte");
|
|
||||||
|
|
||||||
dut_unpack.request.put(got);
|
|
||||||
if (testflags.verbose)
|
|
||||||
$display("unpack.put(%0d), binary %08b", got, got);
|
|
||||||
endaction;
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function Action check_unpack(UInt#(17) want);
|
|
||||||
return action
|
|
||||||
let got <- dut_unpack.response.get();
|
|
||||||
if (testflags.verbose)
|
|
||||||
$display("unpack.get = %0d (%08b), want %0d (%08b)", got, got, want, want);
|
|
||||||
dynamicAssert(got == want, "got incorrect unpacked value");
|
|
||||||
endaction;
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
runTest(100,
|
|
||||||
mkTest("PackUnpack", seq
|
|
||||||
put_pack(115738);
|
|
||||||
check_pack(8'b00000001);
|
|
||||||
check_pack(8'b11000100);
|
|
||||||
check_pack(8'b00011010);
|
|
||||||
check_unpack(115738);
|
|
||||||
|
|
||||||
put_pack(0);
|
|
||||||
check_pack(0);
|
|
||||||
check_pack(0);
|
|
||||||
check_pack(0);
|
|
||||||
check_unpack(0);
|
|
||||||
endseq));
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
endpackage
|
|
4
tasks.py
4
tasks.py
|
@ -137,7 +137,7 @@ def build(c, target):
|
||||||
return verilog_files
|
return verilog_files
|
||||||
|
|
||||||
@task
|
@task
|
||||||
def synth(c, target, gui=False, new_placer=False):
|
def synth(c, target, gui=False):
|
||||||
target = resolve_synth_target(target)
|
target = resolve_synth_target(target)
|
||||||
|
|
||||||
out_info, out_verilog, out_bsc, out_yosys, out_nextpnr = ensure_build_dirs(target, "info", "verilog", "bsc", "yosys", "nextpnr")
|
out_info, out_verilog, out_bsc, out_yosys, out_nextpnr = ensure_build_dirs(target, "info", "verilog", "bsc", "yosys", "nextpnr")
|
||||||
|
@ -201,8 +201,6 @@ def synth(c, target, gui=False, new_placer=False):
|
||||||
cmd = f"nextpnr-ecp5 --85k --detailed-timing-report --report {nextpnr_timing} --json {yosys_json} --gui --gui-no-aa --package=CABGA381 {pin_map_arg} --speed=6 --textcfg {nextpnr_out}"
|
cmd = f"nextpnr-ecp5 --85k --detailed-timing-report --report {nextpnr_timing} --json {yosys_json} --gui --gui-no-aa --package=CABGA381 {pin_map_arg} --speed=6 --textcfg {nextpnr_out}"
|
||||||
else:
|
else:
|
||||||
cmd = f"nextpnr-ecp5 --85k --detailed-timing-report -l {nextpnr_log} --report {nextpnr_timing} --json {yosys_json} --write {nextpnr_out_json} --package=CABGA381 {pin_map_arg} --speed=6 --textcfg {nextpnr_out}"
|
cmd = f"nextpnr-ecp5 --85k --detailed-timing-report -l {nextpnr_log} --report {nextpnr_timing} --json {yosys_json} --write {nextpnr_out_json} --package=CABGA381 {pin_map_arg} --speed=6 --textcfg {nextpnr_out}"
|
||||||
if new_placer:
|
|
||||||
cmd += f" --placer static"
|
|
||||||
out = c.run(cmd)
|
out = c.run(cmd)
|
||||||
|
|
||||||
print_filtered_paragraphs(out.stderr, "Device utilisation", "Critical path", "Max frequency", "Max delay", common_prefix="Info: ")
|
print_filtered_paragraphs(out.stderr, "Device utilisation", "Critical path", "Max frequency", "Max delay", common_prefix="Info: ")
|
||||||
|
|
Loading…
Reference in New Issue