diff --git a/examples/nexys_a7/io_core/foo.v b/examples/nexys_a7/io_core/foo.v deleted file mode 100644 index 433a9b0..0000000 --- a/examples/nexys_a7/io_core/foo.v +++ /dev/null @@ -1,473 +0,0 @@ -`default_nettype none -`timescale 1ns/1ps - -/* -This manta definition was generated on 16 Mar 2023 at 09:36:48 by fischerm - -If this breaks or if you've got dank formal verification memes, -please contact fischerm [at] mit.edu - -Provided under a GNU GPLv3 license. Go wild. -*/ - -module manta ( - input wire clk, - - input wire rx, - output reg tx); - - rx_uart #(.CLOCKS_PER_BAUD(868)) urx ( - .i_clk(clk), - .i_uart_rx(rx), - .o_wr(urx_brx_axiv), - .o_data(urx_brx_axid)); - - logic [7:0] urx_brx_axid; - logic urx_brx_axiv; - - bridge_rx brx ( - .clk(clk), - - .rx_data(urx_brx_axid), - .rx_valid(urx_brx_axiv), - - .addr_o(brx_my_io_core_addr), - .wdata_o(brx_my_io_core_wdata), - .rw_o(brx_my_io_core_rw), - .valid_o(brx_my_io_core_valid)); - - reg [15:0] brx_my_io_core_addr; - reg [15:0] brx_my_io_core_wdata; - reg brx_my_io_core_rw; - reg brx_my_io_core_valid; - - reg [15:0] my_io_core_btx_rdata; - reg my_io_core_btx_rw; - reg my_io_core_btx_valid; - - bridge_tx btx ( - .clk(clk), - - .rdata_i(my_io_core_btx_rdata), - .rw_i(my_io_core_btx_rw), - .valid_i(my_io_core_btx_valid), - - .ready_i(utx_btx_ready), - .data_o(btx_utx_data), - .valid_o(btx_utx_valid)); - - logic utx_btx_ready; - logic btx_utx_valid; - logic [7:0] btx_utx_data; - - uart_tx #(.CLOCKS_PER_BAUD(868)) utx ( - .clk(clk), - - .data(btx_utx_data), - .valid(btx_utx_valid), - .ready(utx_btx_ready), - - .tx(tx)); -endmodule - - /* ---- Module Definitions ---- */ -//////////////////////////////////////////////////////////////////////////////// -// -// Filename: rxuart.v -// -// Project: Verilog Tutorial Example file -// -// Purpose: Receives a character from a UART (serial port) wire. Key -// features of this core include: -// -// - The baud rate is constant, and set by the CLOCKS_PER_BAUD parameter. -// To be successful, one baud interval must be (approximately) -// equal to CLOCKS_PER_BAUD / CLOCK_RATE_HZ seconds long. -// -// - The protocol used is the basic 8N1: 8 data bits, 1 stop bit, and no -// parity. -// -// - This core has no reset -// - This core has no error detection for frame errors -// - This core cannot detect, report, or even recover from, a break -// condition on the line. A break condition is defined as a -// period of time where the i_uart_rx line is held low for longer -// than one data byte (10 baud intervals) -// -// - There's no clock rate detection in this core -// -// Perhaps one of the nicer features of this core is that it (can be) -// formally verified. It depends upon a separate (formally verified) -// transmit core for this purpose. -// -// As with the other cores within this tutorial, there may (or may not) be -// bugs within this design for you to find. -// -// -// Creator: Dan Gisselquist, Ph.D. -// Gisselquist Technology, LLC -// -//////////////////////////////////////////////////////////////////////////////// -// -// Written and distributed by Gisselquist Technology, LLC -// -// This program is hereby granted to the public domain. -// -// This program is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -//////////////////////////////////////////////////////////////////////////////// -// -// - - -module rx_uart( - input wire i_clk, - input wire i_uart_rx, - output reg o_wr, - output reg [7:0] o_data); - - parameter [15:0] CLOCKS_PER_BAUD = 868; - localparam [3:0] IDLE = 4'h0; - localparam [3:0] BIT_ZERO = 4'h1; - // localparam [3:0] BIT_ONE = 4'h2; - // localparam [3:0] BIT_TWO = 4'h3; - // localparam [3:0] BIT_THREE = 4'h4; - // localparam [3:0] BIT_FOUR = 4'h5; - // localparam [3:0] BIT_FIVE = 4'h6; - // localparam [3:0] BIT_SIX = 4'h7; - // localparam [3:0] BIT_SEVEN = 4'h8; - localparam [3:0] STOP_BIT = 4'h9; - - reg [3:0] state; - reg [15:0] baud_counter; - reg zero_baud_counter; - - // 2FF Synchronizer - // - reg ck_uart; - reg q_uart; - initial { ck_uart, q_uart } = -1; - always @(posedge i_clk) - { ck_uart, q_uart } <= { q_uart, i_uart_rx }; - - initial state = IDLE; - initial baud_counter = 0; - - always @(posedge i_clk) - if (state == IDLE) begin - state <= IDLE; - baud_counter <= 0; - if (!ck_uart) begin - state <= BIT_ZERO; - baud_counter <= CLOCKS_PER_BAUD+CLOCKS_PER_BAUD/2-1'b1; - end - end - - else if (zero_baud_counter) begin - state <= state + 1; - baud_counter <= CLOCKS_PER_BAUD-1'b1; - if (state == STOP_BIT) begin - state <= IDLE; - baud_counter <= 0; - end - end - - else baud_counter <= baud_counter - 1'b1; - - always @(*) - zero_baud_counter = (baud_counter == 0); - - always @(posedge i_clk) - if ((zero_baud_counter)&&(state != STOP_BIT)) - o_data <= { ck_uart, o_data[7:1] }; - - initial o_wr = 1'b0; - always @(posedge i_clk) - o_wr <= ((zero_baud_counter)&&(state == STOP_BIT)); - -endmodule - - - - -module bridge_rx( - input wire clk, - - input wire[7:0] rx_data, - input wire rx_valid, - - output reg[15:0] addr_o, - output reg[15:0] wdata_o, - output reg rw_o, - output reg valid_o -); - - -// this is a hack, the FSM needs to be updated -// but this will bypass it for now -parameter ready_i = 1; - -parameter ADDR_WIDTH = 0; -parameter DATA_WIDTH = 0; - -localparam PREAMBLE = 8'h4D; -localparam CR = 8'h0D; -localparam LF = 8'h0A; - -localparam ACQUIRE = 0; -localparam TRANSMIT = 1; -localparam ERROR = 2; - -reg [1:0] state; -reg [3:0] bytes_received; - -// no global resets! -initial begin - addr_o = 0; - wdata_o = 0; - rw_o = 0; - valid_o = 0; - bytes_received = 0; - state = ACQUIRE; -end - -reg [3:0] rx_data_decoded; -reg rx_data_is_0_thru_9; -reg rx_data_is_A_thru_F; - -always @(*) begin - rx_data_is_0_thru_9 = (rx_data >= 8'h30) & (rx_data <= 8'h39); - rx_data_is_A_thru_F = (rx_data >= 8'h41) & (rx_data <= 8'h46); - - if (rx_data_is_0_thru_9) rx_data_decoded = rx_data - 8'h30; - else if (rx_data_is_A_thru_F) rx_data_decoded = rx_data - 8'h41 + 'd10; - else rx_data_decoded = 0; -end - - -always @(posedge clk) begin - if (state == ACQUIRE) begin - if(rx_valid) begin - - if (bytes_received == 0) begin - if(rx_data == PREAMBLE) bytes_received <= 1; - end - - else if( (bytes_received >= 1) & (bytes_received <= 4) ) begin - // only advance if byte is valid hex digit - if(rx_data_is_0_thru_9 | rx_data_is_A_thru_F) begin - addr_o <= (addr_o << 4) | rx_data_decoded; - bytes_received <= bytes_received + 1; - end - - else state <= ERROR; - end - - else if( bytes_received == 5) begin - if( (rx_data == CR) | (rx_data == LF)) begin - valid_o <= 1; - rw_o = 0; - bytes_received <= 0; - state <= TRANSMIT; - end - - else if (rx_data_is_0_thru_9 | rx_data_is_A_thru_F) begin - bytes_received <= bytes_received + 1; - wdata_o <= (wdata_o << 4) | rx_data_decoded; - end - - else state <= ERROR; - end - - else if ( (bytes_received >= 6) & (bytes_received <= 8) ) begin - - if (rx_data_is_0_thru_9 | rx_data_is_A_thru_F) begin - wdata_o <= (wdata_o << 4) | rx_data_decoded; - bytes_received <= bytes_received + 1; - end - - else state <= ERROR; - end - - else if (bytes_received == 9) begin - bytes_received <= 0; - if( (rx_data == CR) | (rx_data == LF)) begin - valid_o <= 1; - rw_o <= 1; - state <= TRANSMIT; - end - - else state <= ERROR; - end - end - end - - - else if (state == TRANSMIT) begin - if(ready_i) begin - valid_o <= 0; - state <= ACQUIRE; - end - - if(rx_valid) begin - if ( (rx_data != CR) & (rx_data != LF)) begin - valid_o <= 0; - state <= ERROR; - end - end - end -end - -endmodule - - - - - -module bridge_tx( - input wire clk, - - input wire [15:0] rdata_i, - input wire rw_i, - input wire valid_i, - - output reg [7:0] data_o, - input wire ready_i, - output reg valid_o); - -localparam PREAMBLE = 8'h4D; -localparam CR = 8'h0D; -localparam LF = 8'h0A; - -logic busy; -logic [15:0] buffer; -logic [3:0] byte_counter; - -initial begin - busy = 0; - buffer = 0; - byte_counter = 0; - valid_o = 0; -end - -always @(posedge clk) begin - if (!busy) begin - if (valid_i && !rw_i) begin - busy <= 1; - buffer <= rdata_i; - byte_counter <= 0; - valid_o <= 1; - end - end - - if (busy) begin - - if(ready_i) begin - byte_counter <= byte_counter + 1; - - if (byte_counter > 5) begin - byte_counter <= 0; - - // stop transmitting if we don't have both valid and read - if ( !(valid_i && !rw_i) ) begin - busy <= 0; - valid_o <= 0; - end - end - end - end -end - -always @(*) begin - case (byte_counter) - 0: data_o = PREAMBLE; - 1: data_o = (buffer[15:12] < 10) ? (buffer[15:12] + 8'h30) : (buffer[15:12] + 8'h41 - 'd10); - 2: data_o = (buffer[11:8] < 10) ? (buffer[11:8] + 8'h30) : (buffer[11:8] + 8'h41 - 'd10); - 3: data_o = (buffer[7:4] < 10) ? (buffer[7:4] + 8'h30) : (buffer[7:4] + 8'h41 - 'd10); - 4: data_o = (buffer[3:0] < 10) ? (buffer[3:0] + 8'h30) : (buffer[3:0] + 8'h41 - 'd10); - 5: data_o = CR; - 6: data_o = LF; - default: data_o = 0; - endcase -end - -endmodule - - - - -module uart_tx( - input wire clk, - - input wire [7:0] data, - input wire valid, - output reg busy, - output reg ready, - - output reg tx); - - // this transmitter only works with 8N1 serial, at configurable baudrate - parameter CLOCKS_PER_BAUD = 868; - - reg [9:0] baud_counter; - reg [8:0] data_buf; - reg [3:0] bit_index; - - initial begin - baud_counter = CLOCKS_PER_BAUD; - data_buf = 0; - bit_index = 0; - busy = 0; - ready = 1; - tx = 1; - end - - always @(posedge clk) begin - if (valid && !busy) begin - data_buf <= {1'b1, data}; - bit_index <= 0; - tx <= 0; //wafflestomp that start bit - baud_counter <= CLOCKS_PER_BAUD - 1; - busy <= 1; - ready <= 0; - end - - else if (busy) begin - baud_counter <= baud_counter - 1; - - ready <= (baud_counter == 1) && (bit_index == 9); - - if (baud_counter == 0) begin - baud_counter <= CLOCKS_PER_BAUD - 1; - - - if (bit_index == 9) begin - if(valid) begin - data_buf <= {1'b1, data}; - bit_index <= 0; - tx <= 0; - end - - else begin - busy <= 0; - ready <= 1; - end - // if valid happens here then we should bool - end - - else begin - tx <= data_buf[bit_index]; - bit_index <= bit_index + 1; - end - end - end - end - - - -endmodule - - -`default_nettype wire \ No newline at end of file diff --git a/examples/nexys_a7/io_core/lab-bc.py b/examples/nexys_a7/io_core/lab-bc.py new file mode 100644 index 0000000..d651852 --- /dev/null +++ b/examples/nexys_a7/io_core/lab-bc.py @@ -0,0 +1,301 @@ +import atexit +import getopt +import os +import subprocess +import signal +import sys +import time +import pathlib +import platform + +progname = sys.argv[0] + +diagnostics = False +quiet = False +verbose = False + +port = 80 +machine = "eecs-digital-56.mit.edu" +projectdir = "." +of = "obj" + +p = False + +user = "builder" +outfile = f"{of}/out.bit" +logfile = f"{of}/build.log" + +synthrpt = [ + "report_timing", + "report_timing_summary", + "report_utilization", +] + +placerpt = synthrpt.copy() +placerpt.extend(["report_clock_utilization"]) + +routerpt = [ + "report_drc", + "report_power", + "report_route_status", + "report_timing", + "report_timing_summary", +] + +usagestr = f""" +{progname}: build SystemVerilog code remotely for 2022 6.205 labs +usage: {progname} [-dqv] [-m machine] [-p projectdir] [-o dir] +options: + -d: emit additional diagnostics during synthesis/implementation + -q: quiet: do not generate any vivado logs except for errors. + -v: be verbose (for debugging stuffs / if you see a bug) + -m: override the DNS name queried to perform the build. use with care. + -p: build the project located in projectdir (default is '.') + -o: set the output products directory (default is {of}) +""" + + +def debuglog(s): + if verbose: + print(s) + + +def usage(): + print(usagestr) + sys.exit(1) + + +def getargs(): + global diagnostics + global quiet + global machine + global logfile + global outfile + global projectdir + global of + global verbose + + try: + opts, args = getopt.getopt(sys.argv[1:], "dm:o:p:qv") + except getopt.GetoptError as err: + print(err) + usage() + + if args: + usage() + for o, v in opts: + if o == "-d": + diagnostics = True + elif o == "-q": + quiet = True + elif o == "-m": + machine = v + elif o == "-p": + projectdir = v + elif o == "-o": + of = v + elif o == "-v": + verbose = True + else: + print(f"unrecognized option {o}") + usage() + + outfile = f"{of}/out.bit" + logfile = f"{of}/build.log" + + +def make_posix(path): + return str(pathlib.Path(path).as_posix()) + + +def regfiles(): + ftt = {} + debuglog(f"projectdir is {projectdir}") + for dirpath, subdirs, files in os.walk(projectdir): + if ( + "src" not in dirpath + and "xdc" not in dirpath + and "data" not in dirpath + and "ip" not in dirpath + ): + continue + if dirpath.startswith("./"): + dirpath = dirpath[2:] + for file in files: + fpath = os.path.join(dirpath, file) + debuglog(f"considering {fpath}") + fpath = make_posix(fpath) + + if file.lower().endswith(".v"): + ftt[fpath] = "source" + elif file.lower().endswith(".sv"): + ftt[fpath] = "source" + elif file.lower().endswith(".vh"): + ftt[fpath] = "source" + elif file.lower().endswith(".svh"): + ftt[fpath] = "source" + elif file.lower().endswith(".xdc"): + ftt[fpath] = "xdc" + elif file.lower().endswith(".mem"): + ftt[fpath] = "mem" + elif file.lower().endswith(".xci"): + ftt[fpath] = "ip" + elif file.lower().endswith(".prj"): + ftt[fpath] = "mig" + + debuglog(f"elaborated file list {ftt}") + return ftt + + +# messages are newline delineated per lab-bs.1 +# utilize this to cheat a little bit +def spqsend(p, msg): + debuglog(f"writing {len(msg)} bytes over the wire") + debuglog(f"full message: {msg}") + p.stdin.write(msg + b"\n") + p.stdin.flush() + + +def spsend(p, msg): + debuglog(f"running {msg}") + p.stdin.write((msg + "\n").encode()) + p.stdin.flush() + + +def sprecv(p): + l = p.stdout.readline().decode() + debuglog(f"got {l}") + return l + + +def xsprecv(p): + l = sprecv(p) + if l.startswith("ERR"): + print("received unexpected server error!") + print(l) + sys.exit(1) + return l + + +def spstart(xargv): + debuglog(f"spawning {xargv}") + p = subprocess.PIPE + return subprocess.Popen(xargv, stdin=p, stdout=p, stderr=p) + + +def copyfiles(p, ftt): + for f, t in ftt.items(): + fsize = os.path.getsize(f) + with open(f, "rb") as fd: + spsend(p, f"write {f} {fsize}") + time.sleep(0.1) # ? + spqsend(p, fd.read()) + xsprecv(p) + + spsend(p, f"type {f} {t}") + xsprecv(p) + + +# size message returns ... %zu bytes +def readfile(p, file, targetfile): + spsend(p, f"size {file}") + size = int(xsprecv(p).split()[-2]) + spsend(p, f"read {file}") + + with open(targetfile, "wb+") as fd: + fd.write(p.stdout.read(size)) + + xsprecv(p) + + +def build(p): + cmd = "build" + if diagnostics: + cmd += " -d" + if quiet: + cmd += " -q" + cmd += f" obj" + + print(f"Output target will be {outfile}") + + spsend(p, cmd) + print("Building your code ... (this may take a while, be patient)") + result = sprecv(p) + + if result.startswith("ERR"): + print("Something went wrong!") + else: + readfile(p, "obj/out.bit", outfile) + print(f"Build succeeded, output at {outfile}") + + readfile(p, "obj/build.log", logfile) + print(f"Log file available at {logfile}") + + if diagnostics: + for rpt in synthrpt: + readfile(p, f"obj/synthrpt_{rpt}.rpt", f"{of}/synthrpt_{rpt}.rpt") + for rpt in placerpt: + readfile(p, f"obj/placerpt_{rpt}.rpt", f"{of}/placerpt_{rpt}.rpt") + for rpt in routerpt: + readfile(p, f"obj/routerpt_{rpt}.rpt", f"{of}/routerpt_{rpt}.rpt") + print(f"Diagnostics available in {of}") + + +def main(): + global p + getargs() + ftt = regfiles() + + if not os.path.isdir(of): + print(f"output path {of} does not exist! create it or use -o?") + usage() + + if platform.system() == "Darwin" or platform.system() == "Linux": + xargv = [ + "ssh", + "-p", + f"{port}", + "-o", + "StrictHostKeyChecking=no", + "-o", + "UserKnownHostsFile=/dev/null", + ] + + elif platform.system() == "Windows": + xargv = [ + "ssh", + "-p", + f"{port}", + "-o", + "StrictHostKeyChecking=no", + "-o", + "UserKnownHostsFile=nul", + ] + + else: + raise RuntimeError( + "Your OS is not recognized, unsure of how to format SSH command." + ) + + xargv.append(f"{user}@{machine}") + p = spstart(xargv) + + spsend(p, "help") + result = xsprecv(p) + debuglog(result) + + copyfiles(p, ftt) + build(p) + spsend(p, "exit") + p.wait() + + +if __name__ == "__main__": + try: + main() + except (Exception, KeyboardInterrupt) as e: + if p: + debuglog("killing ssh") + os.kill(p.pid, signal.SIGINT) + p.wait() + raise e diff --git a/examples/nexys_a7/io_core/manta.yaml b/examples/nexys_a7/io_core/manta.yaml index 746ab1d..6993b85 100644 --- a/examples/nexys_a7/io_core/manta.yaml +++ b/examples/nexys_a7/io_core/manta.yaml @@ -1,19 +1,24 @@ --- cores: my_io_core: - type: io - + type: io + inputs: - picard: 1 - data: 7 - laforge: 10 - troi: 1 - + btnu: 1 + btnd: 1 + btnl: 1 + btnr: 1 + btnc: 1 + sw: 16 + outputs: - kirk: 1 - spock: 5 - uhura: 3 - chekov: 1 + led: 16 + led16_b: 1 + led16_g: 1 + led16_r: 1 + led17_b: 1 + led17_g: 1 + led17_r: 1 uart: port: "/dev/tty.usbserial-2102926963071" diff --git a/examples/nexys_a7/io_core/src/manta.v b/examples/nexys_a7/io_core/src/manta.v index eda13af..bd2958b 100644 --- a/examples/nexys_a7/io_core/src/manta.v +++ b/examples/nexys_a7/io_core/src/manta.v @@ -2,7 +2,7 @@ `timescale 1ns/1ps /* -This manta definition was generated on 14 Mar 2023 at 13:06:49 by fischerm +This manta definition was generated on 16 Mar 2023 at 12:07:39 by fischerm If this breaks or if you've got dank formal verification memes, please contact fischerm [at] mit.edu @@ -16,10 +16,19 @@ module manta ( input wire rx, output reg tx, - input wire larry, - input wire curly, - input wire moe, - input wire [3:0] shemp); + input wire btnu, + input wire btnd, + input wire btnl, + input wire btnr, + input wire btnc, + input wire [15:0] sw, + output reg [15:0] led, + output reg led16_b, + output reg led16_g, + output reg led16_r, + output reg led17_b, + output reg led17_g, + output reg led17_r); rx_uart #(.CLOCKS_PER_BAUD(868)) urx ( .i_clk(clk), @@ -36,46 +45,59 @@ module manta ( .rx_data(urx_brx_axid), .rx_valid(urx_brx_axiv), - .addr_o(brx_my_logic_analyzer_addr), - .wdata_o(brx_my_logic_analyzer_wdata), - .rw_o(brx_my_logic_analyzer_rw), - .valid_o(brx_my_logic_analyzer_valid)); + .addr_o(brx_my_io_core_addr), + .wdata_o(brx_my_io_core_wdata), + .rw_o(brx_my_io_core_rw), + .valid_o(brx_my_io_core_valid)); - reg [15:0] brx_my_logic_analyzer_addr; - reg [15:0] brx_my_logic_analyzer_wdata; - reg brx_my_logic_analyzer_rw; - reg brx_my_logic_analyzer_valid; + reg [15:0] brx_my_io_core_addr; + reg [15:0] brx_my_io_core_wdata; + reg brx_my_io_core_rw; + reg brx_my_io_core_valid; - la_core my_logic_analyzer ( - .clk(clk), +my_io_core my_io_core_inst( + .clk(clk), - .addr_i(brx_my_logic_analyzer_addr), - .wdata_i(brx_my_logic_analyzer_wdata), - .rdata_i(), - .rw_i(brx_my_logic_analyzer_rw), - .valid_i(brx_my_logic_analyzer_valid), + // ports + .btnu(btnu), + .btnd(btnd), + .btnl(btnl), + .btnr(btnr), + .btnc(btnc), + .sw(sw), + .led(led), + .led16_b(led16_b), + .led16_g(led16_g), + .led16_r(led16_r), + .led17_b(led17_b), + .led17_g(led17_g), + .led17_r(led17_r), - .larry(larry), - .curly(curly), - .moe(moe), - .shemp(shemp), - - .addr_o(), - .wdata_o(), - .rdata_o(my_logic_analyzer_btx_rdata), - .rw_o(my_logic_analyzer_btx_rw), - .valid_o(my_logic_analyzer_btx_valid)); + // input port + .addr_i(brx_my_io_core_addr), + .wdata_i(brx_my_io_core_wdata), + .rdata_i(), + .rw_i(brx_my_io_core_rw), + .valid_i(brx_my_io_core_valid), - reg [15:0] my_logic_analyzer_btx_rdata; - reg my_logic_analyzer_btx_rw; - reg my_logic_analyzer_btx_valid; + // output port + .addr_o(), + .wdata_o(), + .rdata_o(my_io_core_btx_rdata), + .rw_o(my_io_core_btx_rw), + .valid_o(my_io_core_btx_valid) + ); + + reg [15:0] my_io_core_btx_rdata; + reg my_io_core_btx_rw; + reg my_io_core_btx_valid; bridge_tx btx ( .clk(clk), - - .rdata_i(my_logic_analyzer_btx_rdata), - .rw_i(my_logic_analyzer_btx_rw), - .valid_i(my_logic_analyzer_btx_valid), + + .rdata_i(my_io_core_btx_rdata), + .rw_i(my_io_core_btx_rw), + .valid_i(my_io_core_btx_valid), .ready_i(utx_btx_ready), .data_o(btx_utx_data), @@ -84,7 +106,7 @@ module manta ( logic utx_btx_ready; logic btx_utx_valid; logic [7:0] btx_utx_data; - + uart_tx #(.CLOCKS_PER_BAUD(868)) utx ( .clk(clk), @@ -348,6 +370,84 @@ end endmodule +module my_io_core ( + input wire clk, + + // ports + input wire btnu, + input wire btnd, + input wire btnl, + input wire btnr, + input wire btnc, + input wire [15:0] sw, + output reg [15:0] led, + output reg led16_b, + output reg led16_g, + output reg led16_r, + output reg led17_b, + output reg led17_g, + output reg led17_r, + + // input port + input wire [15:0] addr_i, + input wire [15:0] wdata_i, + input wire [15:0] rdata_i, + input wire rw_i, + input wire valid_i, + + // output port + output reg [15:0] addr_o, + output reg [15:0] wdata_o, + output reg [15:0] rdata_o, + output reg rw_o, + output reg valid_o + ); + +parameter BASE_ADDR = 0; +always @(posedge clk) begin + addr_o <= addr_i; + wdata_o <= wdata_i; + rdata_o <= rdata_i; + rw_o <= rw_i; + valid_o <= valid_i; + rdata_o <= rdata_i; + + + // check if address is valid + if( (valid_i) && (addr_i >= BASE_ADDR) && (addr_i <= BASE_ADDR + 12)) begin + + if(!rw_i) begin // reads + case (addr_i) + BASE_ADDR + 0: rdata_o <= {15'b0, btnu}; + BASE_ADDR + 1: rdata_o <= {15'b0, btnd}; + BASE_ADDR + 2: rdata_o <= {15'b0, btnl}; + BASE_ADDR + 3: rdata_o <= {15'b0, btnr}; + BASE_ADDR + 4: rdata_o <= {15'b0, btnc}; + BASE_ADDR + 5: rdata_o <= sw; + BASE_ADDR + 6: rdata_o <= led; + BASE_ADDR + 7: rdata_o <= {15'b0, led16_b}; + BASE_ADDR + 8: rdata_o <= {15'b0, led16_g}; + BASE_ADDR + 9: rdata_o <= {15'b0, led16_r}; + BASE_ADDR + 10: rdata_o <= {15'b0, led17_b}; + BASE_ADDR + 11: rdata_o <= {15'b0, led17_g}; + BASE_ADDR + 12: rdata_o <= {15'b0, led17_r}; + endcase + end + + else begin // writes + case (addr_i) + BASE_ADDR + 6: led <= wdata_i; + BASE_ADDR + 7: led16_b <= wdata_i[0]; + BASE_ADDR + 8: led16_g <= wdata_i[0]; + BASE_ADDR + 9: led16_r <= wdata_i[0]; + BASE_ADDR + 10: led17_b <= wdata_i[0]; + BASE_ADDR + 11: led17_g <= wdata_i[0]; + BASE_ADDR + 12: led17_r <= wdata_i[0]; + endcase + end + end + end +endmodule diff --git a/examples/nexys_a7/io_core/src/ssd.v b/examples/nexys_a7/io_core/src/ssd.v new file mode 100644 index 0000000..dc27ee4 --- /dev/null +++ b/examples/nexys_a7/io_core/src/ssd.v @@ -0,0 +1,85 @@ +module ssd( + input wire clk_in, + input wire rst_in, + input wire [31:0] val_in, + output reg[6:0] cat_out, + output reg[7:0] an_out); + + parameter COUNT_TO = 100000; + logic[7:0] segment_state; + logic[31:0] segment_counter; + logic [3:0] routed_vals; + logic [6:0] led_out; + + bto7s mbto7s (.x_in(routed_vals), .s_out(led_out)); + + assign cat_out = ~led_out; + assign an_out = ~segment_state; + + always @(*) begin + case(segment_state) + 8'b0000_0001: routed_vals = val_in[3:0]; + 8'b0000_0010: routed_vals = val_in[7:4]; + 8'b0000_0100: routed_vals = val_in[11:8]; + 8'b0000_1000: routed_vals = val_in[15:12]; + 8'b0001_0000: routed_vals = val_in[19:16]; + 8'b0010_0000: routed_vals = val_in[23:20]; + 8'b0100_0000: routed_vals = val_in[27:24]; + 8'b1000_0000: routed_vals = val_in[31:28]; + default: routed_vals = val_in[3:0]; + endcase + end + + always @(posedge clk_in) begin + if (rst_in) begin + segment_state <= 8'b0000_0001; + segment_counter <= 32'b0; + end + + else begin + if (segment_counter == COUNT_TO) begin + segment_counter <= 32'd0; + segment_state <= {segment_state[6:0],segment_state[7]}; + end else begin + segment_counter <= segment_counter +1; + end + end + end +endmodule + + +module bto7s( + input wire [3:0] x_in, + output reg [6:0] s_out); + + reg sa, sb, sc, sd, se, sf, sg; + assign s_out = {sg, sf, se, sd, sc, sb, sa}; + + // array of bits that are "one hot" with numbers 0 through 15 + reg [15:0] num; + + assign num[0] = ~x_in[3] && ~x_in[2] && ~x_in[1] && ~x_in[0]; + assign num[1] = ~x_in[3] && ~x_in[2] && ~x_in[1] && x_in[0]; + assign num[2] = x_in == 4'd2; + assign num[3] = x_in == 4'd3; + assign num[4] = x_in == 4'd4; + assign num[5] = x_in == 4'd5; + assign num[6] = x_in == 4'd6; + assign num[7] = x_in == 4'd7; + assign num[8] = x_in == 4'd8; + assign num[9] = x_in == 4'd9; + assign num[10] = x_in == 4'd10; + assign num[11] = x_in == 4'd11; + assign num[12] = x_in == 4'd12; + assign num[13] = x_in == 4'd13; + assign num[14] = x_in == 4'd14; + assign num[15] = x_in == 4'd15; + + assign sa = num[0] || num[2] || num[3] || num[5] || num[6] || num[7] || num[8] || num[9] || num[10] || num[12] ||num[14] ||num[15]; + assign sb = num[0] || num[1] || num[2] || num[3] || num[4] || num[7] || num[8] || num[9] || num[10] || num[13]; + assign sc = num[0] || num[1] || num[3] || num[4] || num[5] || num[6] || num[7] || num[8] || num[9] || num[10] || num[11] || num[13]; + assign sd = num[0] || num[2] || num[3] || num[5] || num[6] || num[8] || num[9] || num[11] || num[12] || num[13] || num[14]; + assign se = num[0] || num[2] || num[6] || num[8] || num[10] || num[11] || num[12] || num[13] || num[14] || num[15]; + assign sf = num[0] || num[4] || num[5] || num[6] || num[8] || num[9] || num[10] || num[11] || num[12] || num[14] || num[15]; + assign sg = num[2] || num[3] || num[4] || num[5] || num[6] || num[8] || num[9] || num[10] || num[11] || num[13] || num[14] ||num[15]; +endmodule diff --git a/examples/nexys_a7/io_core/src/top_level.sv b/examples/nexys_a7/io_core/src/top_level.sv new file mode 100644 index 0000000..b7e09b9 --- /dev/null +++ b/examples/nexys_a7/io_core/src/top_level.sv @@ -0,0 +1,63 @@ +`default_nettype none +`timescale 1ns / 1ps + +module top_level ( + input wire clk, + input wire cpu_resetn, + + input wire btnu, + input wire btnd, + input wire btnl, + input wire btnr, + input wire btnc, + + input wire [15:0] sw, + + output logic [15:0] led, + output logic led16_b, + output logic led16_g, + output logic led16_r, + output logic led17_b, + output logic led17_g, + output logic led17_r, + + + output logic ca, cb, cc, cd, ce, cf, cg, + output logic [7:0] an, + + input wire uart_txd_in, + output logic uart_rxd_out + ); + + manta manta ( + .clk(clk), + + .rx(uart_txd_in), + .tx(uart_rxd_out), + + .btnu(btnu), + .btnd(btnd), + .btnl(btnl), + .btnr(btnr), + .btnc(btnc), + .sw(sw), + .led(led), + .led16_b(led16_b), + .led16_g(led16_g), + .led16_r(led16_r), + .led17_b(led17_b), + .led17_g(led17_g), + .led17_r(led17_r)); + + logic [6:0] cat; + assign {cg,cf,ce,cd,cc,cb,ca} = cat; + ssd ssd ( + .clk_in(clk), + .rst_in(cpu_resetn), + .val_in( (manta.my_io_core_btx_rdata << 16) | (manta.brx_my_io_core_wdata) ), + .cat_out(cat), + .an_out(an)); + +endmodule + +`default_nettype wire \ No newline at end of file diff --git a/examples/nexys_a7/io_core/xdc/top_level.xdc b/examples/nexys_a7/io_core/xdc/top_level.xdc new file mode 100644 index 0000000..fca36e0 --- /dev/null +++ b/examples/nexys_a7/io_core/xdc/top_level.xdc @@ -0,0 +1,260 @@ +## R1.0 2019-08-27 +## Updated by jodalyst in 2020-2022 +## all inputs/outputs changed to lowercase; arrays start with zero. +## system clock renamed to clk +## ja, jb, jc, jd renamed to 0-7 +## xa port renamed 0-3 +## seven segments renamed to a,b,c,d,e,f,dp + +## This file is a general .xdc for the Nexys4 DDR Rev. C +## To use it in a project: +## - uncomment the lines corresponding to used pins +## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project + +## Clock signal - uncomment _both_ of these lines to create clk_100mhz +set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { clk }]; #IO_L12P_T1_MRCC_35 Sch=clk +create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports {clk}]; + +##Switches + +set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { sw[0] }]; #IO_L24N_T3_RS0_15 Sch=sw[0] +set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 } [get_ports { sw[1] }]; #IO_L3N_T0_DQS_EMCCLK_14 Sch=sw[1] +set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports { sw[2] }]; #IO_L6N_T0_D08_VREF_14 Sch=sw[2] +set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { sw[3] }]; #IO_L13N_T2_MRCC_14 Sch=sw[3] +set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 } [get_ports { sw[4] }]; #IO_L12N_T1_MRCC_14 Sch=sw[4] +set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 } [get_ports { sw[5] }]; #IO_L7N_T1_D10_14 Sch=sw[5] +set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { sw[6] }]; #IO_L17N_T2_A13_D29_14 Sch=sw[6] +set_property -dict { PACKAGE_PIN R13 IOSTANDARD LVCMOS33 } [get_ports { sw[7] }]; #IO_L5N_T0_D07_14 Sch=sw[7] +set_property -dict { PACKAGE_PIN T8 IOSTANDARD LVCMOS18 } [get_ports { sw[8] }]; #IO_L24N_T3_34 Sch=sw[8] +set_property -dict { PACKAGE_PIN U8 IOSTANDARD LVCMOS18 } [get_ports { sw[9] }]; #IO_25_34 Sch=sw[9] +set_property -dict { PACKAGE_PIN R16 IOSTANDARD LVCMOS33 } [get_ports { sw[10] }]; #IO_L15P_T2_DQS_RDWR_B_14 Sch=sw[10] +set_property -dict { PACKAGE_PIN T13 IOSTANDARD LVCMOS33 } [get_ports { sw[11] }]; #IO_L23P_T3_A03_D19_14 Sch=sw[11] +set_property -dict { PACKAGE_PIN H6 IOSTANDARD LVCMOS33 } [get_ports { sw[12] }]; #IO_L24P_T3_35 Sch=sw[12] +set_property -dict { PACKAGE_PIN U12 IOSTANDARD LVCMOS33 } [get_ports { sw[13] }]; #IO_L20P_T3_A08_D24_14 Sch=sw[13] +set_property -dict { PACKAGE_PIN U11 IOSTANDARD LVCMOS33 } [get_ports { sw[14] }]; #IO_L19N_T3_A09_D25_VREF_14 Sch=sw[14] +set_property -dict { PACKAGE_PIN V10 IOSTANDARD LVCMOS33 } [get_ports { sw[15] }]; #IO_L21P_T3_DQS_14 Sch=sw[15] + + +## LEDs + +set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { led[0] }]; #IO_L18P_T2_A24_15 Sch=led[0] +set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { led[1] }]; #IO_L24P_T3_RS1_15 Sch=led[1] +set_property -dict { PACKAGE_PIN J13 IOSTANDARD LVCMOS33 } [get_ports { led[2] }]; #IO_L17N_T2_A25_15 Sch=led[2] +set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 } [get_ports { led[3] }]; #IO_L8P_T1_D11_14 Sch=led[3] +set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 } [get_ports { led[4] }]; #IO_L7P_T1_D09_14 Sch=led[4] +set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports { led[5] }]; #IO_L18N_T2_A11_D27_14 Sch=led[5] +set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports { led[6] }]; #IO_L17P_T2_A14_D30_14 Sch=led[6] +set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { led[7] }]; #IO_L18P_T2_A12_D28_14 Sch=led[7] +set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { led[8] }]; #IO_L16N_T2_A15_D31_14 Sch=led[8] +set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS33 } [get_ports { led[9] }]; #IO_L14N_T2_SRCC_14 Sch=led[9] +set_property -dict { PACKAGE_PIN U14 IOSTANDARD LVCMOS33 } [get_ports { led[10] }]; #IO_L22P_T3_A05_D21_14 Sch=led[10] +set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS33 } [get_ports { led[11] }]; #IO_L15N_T2_DQS_DOUT_CSO_B_14 Sch=led[11] +set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports { led[12] }]; #IO_L16P_T2_CSI_B_14 Sch=led[12] +set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports { led[13] }]; #IO_L22N_T3_A04_D20_14 Sch=led[13] +set_property -dict { PACKAGE_PIN V12 IOSTANDARD LVCMOS33 } [get_ports { led[14] }]; #IO_L20N_T3_A07_D23_14 Sch=led[14] +set_property -dict { PACKAGE_PIN V11 IOSTANDARD LVCMOS33 } [get_ports { led[15] }]; #IO_L21N_T3_DQS_A06_D22_14 Sch=led[15] + +set_property -dict { PACKAGE_PIN R12 IOSTANDARD LVCMOS33 } [get_ports { led16_b }]; #IO_L5P_T0_D06_14 Sch=led16_b +set_property -dict { PACKAGE_PIN M16 IOSTANDARD LVCMOS33 } [get_ports { led16_g }]; #IO_L10P_T1_D14_14 Sch=led16_g +set_property -dict { PACKAGE_PIN N15 IOSTANDARD LVCMOS33 } [get_ports { led16_r }]; #IO_L11P_T1_SRCC_14 Sch=led16_r +set_property -dict { PACKAGE_PIN G14 IOSTANDARD LVCMOS33 } [get_ports { led17_b }]; #IO_L15N_T2_DQS_ADV_B_15 Sch=led17_b +set_property -dict { PACKAGE_PIN R11 IOSTANDARD LVCMOS33 } [get_ports { led17_g }]; #IO_0_14 Sch=led17_g +set_property -dict { PACKAGE_PIN N16 IOSTANDARD LVCMOS33 } [get_ports { led17_r }]; #IO_L11N_T1_SRCC_14 Sch=led17_r + + +##7 segment display + +set_property -dict { PACKAGE_PIN T10 IOSTANDARD LVCMOS33 } [get_ports { ca }]; #IO_L24N_T3_A00_D16_14 Sch=ca +set_property -dict { PACKAGE_PIN R10 IOSTANDARD LVCMOS33 } [get_ports { cb }]; #IO_25_14 Sch=cb +set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { cc }]; #IO_25_15 Sch=cc +set_property -dict { PACKAGE_PIN K13 IOSTANDARD LVCMOS33 } [get_ports { cd }]; #IO_L17P_T2_A26_15 Sch=cd +set_property -dict { PACKAGE_PIN P15 IOSTANDARD LVCMOS33 } [get_ports { ce }]; #IO_L13P_T2_MRCC_14 Sch=ce +set_property -dict { PACKAGE_PIN T11 IOSTANDARD LVCMOS33 } [get_ports { cf }]; #IO_L19P_T3_A10_D26_14 Sch=cf +set_property -dict { PACKAGE_PIN L18 IOSTANDARD LVCMOS33 } [get_ports { cg }]; #IO_L4P_T0_D04_14 Sch=cg + +# set_property -dict { PACKAGE_PIN H15 IOSTANDARD LVCMOS33 } [get_ports { dp }]; #IO_L19N_T3_A21_VREF_15 Sch=dp + +set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 } [get_ports { an[0] }]; #IO_L23P_T3_FOE_B_15 Sch=an[0] +set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 } [get_ports { an[1] }]; #IO_L23N_T3_FWE_B_15 Sch=an[1] +set_property -dict { PACKAGE_PIN T9 IOSTANDARD LVCMOS33 } [get_ports { an[2] }]; #IO_L24P_T3_A01_D17_14 Sch=an[2] +set_property -dict { PACKAGE_PIN J14 IOSTANDARD LVCMOS33 } [get_ports { an[3] }]; #IO_L19P_T3_A22_15 Sch=an[3] +set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports { an[4] }]; #IO_L8N_T1_D12_14 Sch=an[4] +set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS33 } [get_ports { an[5] }]; #IO_L14P_T2_SRCC_14 Sch=an[5] +set_property -dict { PACKAGE_PIN K2 IOSTANDARD LVCMOS33 } [get_ports { an[6] }]; #IO_L23P_T3_35 Sch=an[6] +set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports { an[7] }]; #IO_L23N_T3_A02_D18_14 Sch=an[7] + + +##Buttons + +set_property -dict { PACKAGE_PIN C12 IOSTANDARD LVCMOS33 } [get_ports { cpu_resetn }]; #IO_L3P_T0_DQS_AD1P_15 Sch=cpu_resetn + +set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 } [get_ports { btnc }]; #IO_L9P_T1_DQS_14 Sch=btnc +set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 } [get_ports { btnu }]; #IO_L4N_T0_D05_14 Sch=btnu +set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 } [get_ports { btnl }]; #IO_L12P_T1_MRCC_14 Sch=btnl +set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 } [get_ports { btnr }]; #IO_L10N_T1_D15_14 Sch=btnr +set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { btnd }]; #IO_L9N_T1_DQS_D13_14 Sch=btnd + + +##Pmod Headers + + +##Pmod Header JA + +#set_property -dict { PACKAGE_PIN C17 IOSTANDARD LVCMOS33 } [get_ports { ja[0] }]; #IO_L20N_T3_A19_15 Sch=ja[1] +#set_property -dict { PACKAGE_PIN D18 IOSTANDARD LVCMOS33 } [get_ports { ja[1] }]; #IO_L21N_T3_DQS_A18_15 Sch=ja[2] +#set_property -dict { PACKAGE_PIN E18 IOSTANDARD LVCMOS33 } [get_ports { ja[2] }]; #IO_L21P_T3_DQS_15 Sch=ja[3] +#set_property -dict { PACKAGE_PIN G17 IOSTANDARD LVCMOS33 } [get_ports { ja[3] }]; #IO_L18N_T2_A23_15 Sch=ja[4] +#set_property -dict { PACKAGE_PIN D17 IOSTANDARD LVCMOS33 } [get_ports { ja[4] }]; #IO_L16N_T2_A27_15 Sch=ja[7] +#set_property -dict { PACKAGE_PIN E17 IOSTANDARD LVCMOS33 } [get_ports { ja[5] }]; #IO_L16P_T2_A28_15 Sch=ja[8] +#set_property -dict { PACKAGE_PIN F18 IOSTANDARD LVCMOS33 } [get_ports { ja[6] }]; #IO_L22N_T3_A16_15 Sch=ja[9] +#set_property -dict { PACKAGE_PIN G18 IOSTANDARD LVCMOS33 } [get_ports { ja[7] }]; #IO_L22P_T3_A17_15 Sch=ja[10] + + +##Pmod Header JB + +#set_property -dict { PACKAGE_PIN D14 IOSTANDARD LVCMOS33 } [get_ports { jb[0] }]; #IO_L1P_T0_AD0P_15 Sch=jb[1] +#set_property -dict { PACKAGE_PIN F16 IOSTANDARD LVCMOS33 } [get_ports { jb[1] }]; #IO_L14N_T2_SRCC_15 Sch=jb[2] +#set_property -dict { PACKAGE_PIN G16 IOSTANDARD LVCMOS33 } [get_ports { jb[2] }]; #IO_L13N_T2_MRCC_15 Sch=jb[3] +#set_property -dict { PACKAGE_PIN H14 IOSTANDARD LVCMOS33 } [get_ports { jb[3] }]; #IO_L15P_T2_DQS_15 Sch=jb[4] +#set_property -dict { PACKAGE_PIN E16 IOSTANDARD LVCMOS33 } [get_ports { jb[4] }]; #IO_L11N_T1_SRCC_15 Sch=jb[7] +#set_property -dict { PACKAGE_PIN F13 IOSTANDARD LVCMOS33 } [get_ports { jb[5] }]; #IO_L5P_T0_AD9P_15 Sch=jb[8] +#set_property -dict { PACKAGE_PIN G13 IOSTANDARD LVCMOS33 } [get_ports { jb[6] }]; #IO_0_15 Sch=jb[9] +#set_property -dict { PACKAGE_PIN H16 IOSTANDARD LVCMOS33 } [get_ports { jb[7] }]; #IO_L13P_T2_MRCC_15 Sch=jb[10] + + +##Pmod Header JC + +#set_property -dict { PACKAGE_PIN K1 IOSTANDARD LVCMOS33 } [get_ports { jc[0] }]; #IO_L23N_T3_35 Sch=jc[1] +#set_property -dict { PACKAGE_PIN F6 IOSTANDARD LVCMOS33 } [get_ports { jc[1] }]; #IO_L19N_T3_VREF_35 Sch=jc[2] +#set_property -dict { PACKAGE_PIN J2 IOSTANDARD LVCMOS33 } [get_ports { jc[2] }]; #IO_L22N_T3_35 Sch=jc[3] +#set_property -dict { PACKAGE_PIN G6 IOSTANDARD LVCMOS33 } [get_ports { jc[3] }]; #IO_L19P_T3_35 Sch=jc[4] +#set_property -dict { PACKAGE_PIN E7 IOSTANDARD LVCMOS33 } [get_ports { jc[4] }]; #IO_L6P_T0_35 Sch=jc[7] +#set_property -dict { PACKAGE_PIN J3 IOSTANDARD LVCMOS33 } [get_ports { jc[5] }]; #IO_L22P_T3_35 Sch=jc[8] +#set_property -dict { PACKAGE_PIN J4 IOSTANDARD LVCMOS33 } [get_ports { jc[6] }]; #IO_L21P_T3_DQS_35 Sch=jc[9] +#set_property -dict { PACKAGE_PIN E6 IOSTANDARD LVCMOS33 } [get_ports { jc[7] }]; #IO_L5P_T0_AD13P_35 Sch=jc[10] + + +##Pmod Header JD + +#set_property -dict { PACKAGE_PIN H4 IOSTANDARD LVCMOS33 } [get_ports { jd[0] }]; #IO_L21N_T3_DQS_35 Sch=jd[1] +#set_property -dict { PACKAGE_PIN H1 IOSTANDARD LVCMOS33 } [get_ports { jd[1] }]; #IO_L17P_T2_35 Sch=jd[2] +#set_property -dict { PACKAGE_PIN G1 IOSTANDARD LVCMOS33 } [get_ports { jd[2] }]; #IO_L17N_T2_35 Sch=jd[3] +#set_property -dict { PACKAGE_PIN G3 IOSTANDARD LVCMOS33 } [get_ports { jd[3] }]; #IO_L20N_T3_35 Sch=jd[4] +#set_property -dict { PACKAGE_PIN H2 IOSTANDARD LVCMOS33 } [get_ports { jd[4] }]; #IO_L15P_T2_DQS_35 Sch=jd[7] +#set_property -dict { PACKAGE_PIN G4 IOSTANDARD LVCMOS33 } [get_ports { jd[5] }]; #IO_L20P_T3_35 Sch=jd[8] +#set_property -dict { PACKAGE_PIN G2 IOSTANDARD LVCMOS33 } [get_ports { jd[6] }]; #IO_L15N_T2_DQS_35 Sch=jd[9] +#set_property -dict { PACKAGE_PIN F3 IOSTANDARD LVCMOS33 } [get_ports { jd[7] }]; #IO_L13N_T2_MRCC_35 Sch=jd[10] + + +##Pmod Header JXADC + +#set_property -dict { PACKAGE_PIN A14 IOSTANDARD LVDS } [get_ports { xa_n[0] }]; #IO_L9N_T1_DQS_AD3N_15 Sch=xa_n[1] +#set_property -dict { PACKAGE_PIN A13 IOSTANDARD LVDS } [get_ports { xa_p[0] }]; #IO_L9P_T1_DQS_AD3P_15 Sch=xa_p[1] +#set_property -dict { PACKAGE_PIN A16 IOSTANDARD LVDS } [get_ports { xa_n[1] }]; #IO_L8N_T1_AD10N_15 Sch=xa_n[2] +#set_property -dict { PACKAGE_PIN A15 IOSTANDARD LVDS } [get_ports { xa_p[1] }]; #IO_L8P_T1_AD10P_15 Sch=xa_p[2] +#set_property -dict { PACKAGE_PIN B17 IOSTANDARD LVDS } [get_ports { xa_n[2] }]; #IO_L7N_T1_AD2N_15 Sch=xa_n[3] +#set_property -dict { PACKAGE_PIN B16 IOSTANDARD LVDS } [get_ports { xa_p[2] }]; #IO_L7P_T1_AD2P_15 Sch=xa_p[3] +#set_property -dict { PACKAGE_PIN A18 IOSTANDARD LVDS } [get_ports { xa_n[3] }]; #IO_L10N_T1_AD11N_15 Sch=xa_n[4] +#set_property -dict { PACKAGE_PIN B18 IOSTANDARD LVDS } [get_ports { xa_p[3] }]; #IO_L10P_T1_AD11P_15 Sch=xa_p[4] + + +##VGA Connector + +#set_property -dict { PACKAGE_PIN A3 IOSTANDARD LVCMOS33 } [get_ports { vga_r[0] }]; #IO_L8N_T1_AD14N_35 Sch=vga_r[0] +#set_property -dict { PACKAGE_PIN B4 IOSTANDARD LVCMOS33 } [get_ports { vga_r[1] }]; #IO_L7N_T1_AD6N_35 Sch=vga_r[1] +#set_property -dict { PACKAGE_PIN C5 IOSTANDARD LVCMOS33 } [get_ports { vga_r[2] }]; #IO_L1N_T0_AD4N_35 Sch=vga_r[2] +#set_property -dict { PACKAGE_PIN A4 IOSTANDARD LVCMOS33 } [get_ports { vga_r[3] }]; #IO_L8P_T1_AD14P_35 Sch=vga_r[3] +# +#set_property -dict { PACKAGE_PIN C6 IOSTANDARD LVCMOS33 } [get_ports { vga_g[0] }]; #IO_L1P_T0_AD4P_35 Sch=vga_g[0] +#set_property -dict { PACKAGE_PIN A5 IOSTANDARD LVCMOS33 } [get_ports { vga_g[1] }]; #IO_L3N_T0_DQS_AD5N_35 Sch=vga_g[1] +#set_property -dict { PACKAGE_PIN B6 IOSTANDARD LVCMOS33 } [get_ports { vga_g[2] }]; #IO_L2N_T0_AD12N_35 Sch=vga_g[2] +#set_property -dict { PACKAGE_PIN A6 IOSTANDARD LVCMOS33 } [get_ports { vga_g[3] }]; #IO_L3P_T0_DQS_AD5P_35 Sch=vga_g[3] +# +#set_property -dict { PACKAGE_PIN B7 IOSTANDARD LVCMOS33 } [get_ports { vga_b[0] }]; #IO_L2P_T0_AD12P_35 Sch=vga_b[0] +#set_property -dict { PACKAGE_PIN C7 IOSTANDARD LVCMOS33 } [get_ports { vga_b[1] }]; #IO_L4N_T0_35 Sch=vga_b[1] +#set_property -dict { PACKAGE_PIN D7 IOSTANDARD LVCMOS33 } [get_ports { vga_b[2] }]; #IO_L6N_T0_VREF_35 Sch=vga_b[2] +#set_property -dict { PACKAGE_PIN D8 IOSTANDARD LVCMOS33 } [get_ports { vga_b[3] }]; #IO_L4P_T0_35 Sch=vga_b[3] + +#set_property -dict { PACKAGE_PIN B11 IOSTANDARD LVCMOS33 } [get_ports { vga_hs }]; #IO_L4P_T0_15 Sch=vga_hs +#set_property -dict { PACKAGE_PIN B12 IOSTANDARD LVCMOS33 } [get_ports { vga_vs }]; #IO_L3N_T0_DQS_AD1N_15 Sch=vga_vs + +##Micro SD Connector + +#set_property -dict { PACKAGE_PIN E2 IOSTANDARD LVCMOS33 } [get_ports { sd_reset }]; #IO_L14P_T2_SRCC_35 Sch=sd_reset +#set_property -dict { PACKAGE_PIN A1 IOSTANDARD LVCMOS33 } [get_ports { sd_cd }]; #IO_L9N_T1_DQS_AD7N_35 Sch=sd_cd +#set_property -dict { PACKAGE_PIN B1 IOSTANDARD LVCMOS33 } [get_ports { sd_sck }]; #IO_L9P_T1_DQS_AD7P_35 Sch=sd_sck +#set_property -dict { PACKAGE_PIN C1 IOSTANDARD LVCMOS33 } [get_ports { sd_cmd }]; #IO_L16N_T2_35 Sch=sd_cmd +#set_property -dict { PACKAGE_PIN C2 IOSTANDARD LVCMOS33 } [get_ports { sd_dat[0] }]; #IO_L16P_T2_35 Sch=sd_dat[0] +#set_property -dict { PACKAGE_PIN E1 IOSTANDARD LVCMOS33 } [get_ports { sd_dat[1] }]; #IO_L18N_T2_35 Sch=sd_dat[1] +#set_property -dict { PACKAGE_PIN F1 IOSTANDARD LVCMOS33 } [get_ports { sd_dat[2] }]; #IO_L18P_T2_35 Sch=sd_dat[2] +#set_property -dict { PACKAGE_PIN D2 IOSTANDARD LVCMOS33 } [get_ports { sd_dat[3] }]; #IO_L14N_T2_SRCC_35 Sch=sd_dat[3] + + +##Accelerometer + +#set_property -dict { PACKAGE_PIN E15 IOSTANDARD LVCMOS33 } [get_ports { acl_miso }]; #IO_L11P_T1_SRCC_15 Sch=acl_miso +#set_property -dict { PACKAGE_PIN F14 IOSTANDARD LVCMOS33 } [get_ports { acl_mosi }]; #IO_L5N_T0_AD9N_15 Sch=acl_mosi +#set_property -dict { PACKAGE_PIN F15 IOSTANDARD LVCMOS33 } [get_ports { acl_sclk }]; #IO_L14P_T2_SRCC_15 Sch=acl_sclk +#set_property -dict { PACKAGE_PIN D15 IOSTANDARD LVCMOS33 } [get_ports { acl_csn }]; #IO_L12P_T1_MRCC_15 Sch=acl_csn +#set_property -dict { PACKAGE_PIN B13 IOSTANDARD LVCMOS33 } [get_ports { acl_int[1] }]; #IO_L2P_T0_AD8P_15 Sch=acl_int[1] +#set_property -dict { PACKAGE_PIN C16 IOSTANDARD LVCMOS33 } [get_ports { acl_int[2] }]; #IO_L20P_T3_A20_15 Sch=acl_int[2] + + +##Temperature Sensor + +#set_property -dict { PACKAGE_PIN C14 IOSTANDARD LVCMOS33 } [get_ports { tmp_scl }]; #IO_L1N_T0_AD0N_15 Sch=tmp_scl +#set_property -dict { PACKAGE_PIN C15 IOSTANDARD LVCMOS33 } [get_ports { tmp_sda }]; #IO_L12N_T1_MRCC_15 Sch=tmp_sda +#set_property -dict { PACKAGE_PIN D13 IOSTANDARD LVCMOS33 } [get_ports { tmp_int }]; #IO_L6N_T0_VREF_15 Sch=tmp_int +#set_property -dict { PACKAGE_PIN B14 IOSTANDARD LVCMOS33 } [get_ports { tmp_ct }]; #IO_L2N_T0_AD8N_15 Sch=tmp_ct + +##Omnidirectional Microphone + +#set_property -dict { PACKAGE_PIN J5 IOSTANDARD LVCMOS33 } [get_ports { m_clk }]; #IO_25_35 Sch=m_clk +#set_property -dict { PACKAGE_PIN H5 IOSTANDARD LVCMOS33 } [get_ports { m_data }]; #IO_L24N_T3_35 Sch=m_data +#set_property -dict { PACKAGE_PIN F5 IOSTANDARD LVCMOS33 } [get_ports { m_lrsel }]; #IO_0_35 Sch=m_lrsel + + +##PWM Audio Amplifier + +#set_property -dict { PACKAGE_PIN A11 IOSTANDARD LVCMOS33 } [get_ports { aud_pwm }]; #IO_L4N_T0_15 Sch=aud_pwm +#set_property -dict { PACKAGE_PIN D12 IOSTANDARD LVCMOS33 } [get_ports { aud_sd }]; #IO_L6P_T0_15 Sch=aud_sd + + +##USB-RS232 Interface + +set_property -dict { PACKAGE_PIN C4 IOSTANDARD LVCMOS33 } [get_ports { uart_txd_in }]; #IO_L7P_T1_AD6P_35 Sch=uart_txd_in +set_property -dict { PACKAGE_PIN D4 IOSTANDARD LVCMOS33 } [get_ports { uart_rxd_out }]; #IO_L11N_T1_SRCC_35 Sch=uart_rxd_out +#set_property -dict { PACKAGE_PIN D3 IOSTANDARD LVCMOS33 } [get_ports { uart_cts }]; #IO_L12N_T1_MRCC_35 Sch=uart_cts +#set_property -dict { PACKAGE_PIN E5 IOSTANDARD LVCMOS33 } [get_ports { uart_rts }]; #IO_L5N_T0_AD13N_35 Sch=uart_rts + +##USB HID (PS/2) + +#set_property -dict { PACKAGE_PIN F4 IOSTANDARD LVCMOS33 } [get_ports { ps2_clk }]; #IO_L13P_T2_MRCC_35 Sch=ps2_clk +#set_property -dict { PACKAGE_PIN B2 IOSTANDARD LVCMOS33 } [get_ports { ps2_data }]; #IO_L10N_T1_AD15N_35 Sch=ps2_data + + +##SMSC Ethernet PHY + +#set_property -dict { PACKAGE_PIN C9 IOSTANDARD LVCMOS33 } [get_ports { eth_mdc }]; #IO_L11P_T1_SRCC_16 Sch=eth_mdc +#set_property -dict { PACKAGE_PIN A9 IOSTANDARD LVCMOS33 } [get_ports { eth_mdio }]; #IO_L14N_T2_SRCC_16 Sch=eth_mdio +#set_property -dict { PACKAGE_PIN B3 IOSTANDARD LVCMOS33 } [get_ports { eth_rstn }]; #IO_L10P_T1_AD15P_35 Sch=eth_rstn +#set_property -dict { PACKAGE_PIN D9 IOSTANDARD LVCMOS33 } [get_ports { eth_crsdv }]; #IO_L6N_T0_VREF_16 Sch=eth_crs/udv +#set_property -dict { PACKAGE_PIN C10 IOSTANDARD LVCMOS33 } [get_ports { eth_rxerr }]; #IO_L13N_T2_MRCC_16 Sch=eth_rxerr +#set_property -dict { PACKAGE_PIN C11 IOSTANDARD LVCMOS33 } [get_ports { eth_rxd[0] }]; #IO_L13P_T2_MRCC_16 Sch=eth_rxd[0] +#set_property -dict { PACKAGE_PIN D10 IOSTANDARD LVCMOS33 } [get_ports { eth_rxd[1] }]; #IO_L19N_T3_VREF_16 Sch=eth_rxd[1] +#set_property -dict { PACKAGE_PIN B9 IOSTANDARD LVCMOS33 } [get_ports { eth_txen }]; #IO_L11N_T1_SRCC_16 Sch=eth_txen +#set_property -dict { PACKAGE_PIN A10 IOSTANDARD LVCMOS33 } [get_ports { eth_txd[0] }]; #IO_L14P_T2_SRCC_16 Sch=eth_txd[0] +#set_property -dict { PACKAGE_PIN A8 IOSTANDARD LVCMOS33 } [get_ports { eth_txd[1] }]; #IO_L12N_T1_MRCC_16 Sch=eth_txd[1] +#set_property -dict { PACKAGE_PIN D5 IOSTANDARD LVCMOS33 } [get_ports { eth_refclk }]; #IO_L11P_T1_SRCC_35 Sch=eth_refclk +#set_property -dict { PACKAGE_PIN B8 IOSTANDARD LVCMOS33 } [get_ports { eth_intn }]; #IO_L12P_T1_MRCC_16 Sch=eth_intn + + +##Quad SPI Flash + +#set_property -dict { PACKAGE_PIN K17 IOSTANDARD LVCMOS33 } [get_ports { qspi_dq[0] }]; #IO_L1P_T0_D00_MOSI_14 Sch=qspi_dq[0] +#set_property -dict { PACKAGE_PIN K18 IOSTANDARD LVCMOS33 } [get_ports { qspi_dq[1] }]; #IO_L1N_T0_D01_DIN_14 Sch=qspi_dq[1] +#set_property -dict { PACKAGE_PIN L14 IOSTANDARD LVCMOS33 } [get_ports { qspi_dq[2] }]; #IO_L2P_T0_D02_14 Sch=qspi_dq[2] +#set_property -dict { PACKAGE_PIN M14 IOSTANDARD LVCMOS33 } [get_ports { qspi_dq[3] }]; #IO_L2N_T0_D03_14 Sch=qspi_dq[3] +#set_property -dict { PACKAGE_PIN L13 IOSTANDARD LVCMOS33 } [get_ports { qspi_csn }]; #IO_L6P_T0_FCS_B_14 Sch=qspi_csn + + diff --git a/src/manta/__init__.py b/src/manta/__init__.py index 05d11e5..0a7d478 100644 --- a/src/manta/__init__.py +++ b/src/manta/__init__.py @@ -43,7 +43,7 @@ class UARTInterface: self.ser.read(bytes) def write(self, bytes): - self.ser.write(bytes) + self.ser.write(bytes) def hdl_top_level_ports(self): # this should return the probes that we want to connect to top-level, but like as a string of verilog @@ -82,12 +82,12 @@ class UARTInterface: .rw_o(), .valid_o()); """ - + def tx_hdl_inst(self): return f""" bridge_tx btx ( .clk(clk), - + .rdata_i(), .rw_i(), .valid_i(), @@ -99,7 +99,7 @@ class UARTInterface: logic utx_btx_ready; logic btx_utx_valid; logic [7:0] btx_utx_data; - + uart_tx #(.CLOCKS_PER_BAUD({self.clocks_per_baud})) utx ( .clk(clk), @@ -121,40 +121,104 @@ class IOCore: self.inputs = [] if 'inputs' in config: for name, width in config["inputs"].items(): - # make sure inputs are of reasonable width + # make sure inputs are of reasonable width assert width > 0, f"Input {name} must have width greater than zero." - + self.inputs.append( {"name": name, "width": width, "address": address} ) self.max_rel_addr = address - address += 1 + address += 1 # add outputs to core self.outputs = [] if 'outputs' in config: for name, width in config["outputs"].items(): - # make sure inputs are of reasonable width - assert width > 0, f"Output {name} must have width greater than zero." - + # make sure inputs are of reasonable width + assert width > 0, f"Output {name} must have width greater than zero." + self.outputs.append( {"name": name, "width": width, "address": address} ) self.max_rel_addr = address address += 1 def hdl_inst(self): - hdl = f"" - return hdl - + inst_ports = "" + for input in self.inputs: + name = input["name"] + inst_ports += f".{name}({name}),\n " + + for output in self.outputs: + name = output["name"] + inst_ports += f".{name}({name}),\n " + + inst_ports = inst_ports.rstrip() + + inst = f""" +{self.name} {self.name}_inst( + .clk(clk), + + // ports + {inst_ports} + + // input port + .addr_i(), + .wdata_i(), + .rdata_i(), + .rw_i(), + .valid_i(), + + // output port + .addr_o(), + .wdata_o(), + .rdata_o(), + .rw_o(), + .valid_o() + ); +""" + return inst + def hdl_def(self): # generate declaration + top_level_ports = ',\n '.join(self.hdl_top_level_ports()) + top_level_ports += ',' + declaration = f""" +module {self.name} ( + input wire clk, + + // ports + {top_level_ports} + + // input port + input wire [15:0] addr_i, + input wire [15:0] wdata_i, + input wire [15:0] rdata_i, + input wire rw_i, + input wire valid_i, + + // output port + output reg [15:0] addr_o, + output reg [15:0] wdata_o, + output reg [15:0] rdata_o, + output reg rw_o, + output reg valid_o + ); +""" + # generate memory handling + + # TODO: clean this up, should just do all the probes at once + # instead of splitting by input/output read_case_statement_body = "" for input in self.inputs: name = input["name"] width = input["width"] address = input["address"] - read_case_statement_body += f"\t\t\tBASE_ADDR + {address}: rdata_o <= {{{16-width}'b0, {name}}}\n" + if width == 16: + read_case_statement_body += f"\t\t\t\t\tBASE_ADDR + {address}: rdata_o <= {name};\n" + + else: + read_case_statement_body += f"\t\t\t\t\tBASE_ADDR + {address}: rdata_o <= {{{16-width}'b0, {name}}};\n" write_case_statement_body = "" for output in self.outputs: @@ -162,18 +226,28 @@ class IOCore: width = output["width"] address = output["address"] - read_case_statement_body += f"\t\t\tBASE_ADDR + {address}: rdata_o <= {{{16-width}'b0, {name}}}\n" + if width == 16: + read_case_statement_body += f"\t\t\t\t\tBASE_ADDR + {address}: rdata_o <= {name};\n" + + else: + read_case_statement_body += f"\t\t\t\t\tBASE_ADDR + {address}: rdata_o <= {{{16-width}'b0, {name}}};\n" + if width == 1: - write_case_statement_body += f"\t\t\tBASE_ADDR + {address}: {name} <= wdata_i[0]\n" + write_case_statement_body += f"\t\t\t\t\tBASE_ADDR + {address}: {name} <= wdata_i[0];\n" + + elif width == 16: + write_case_statement_body += f"\t\t\t\t\tBASE_ADDR + {address}: {name} <= wdata_i;\n" + else: - write_case_statement_body += f"\t\t\tBASE_ADDR + {address}: {name} <= wdata_i[{width-1}:0]\n" + write_case_statement_body += f"\t\t\t\t\tBASE_ADDR + {address}: {name} <= wdata_i[{width-1}:0];\n" # remove trailing newline read_case_statement_body = read_case_statement_body.rstrip() write_case_statement_body = write_case_statement_body.rstrip() memory_handler_hdl = f""" +parameter BASE_ADDR = 0; always @(posedge clk) begin addr_o <= addr_i; wdata_o <= wdata_i; @@ -181,7 +255,7 @@ always @(posedge clk) begin rw_o <= rw_i; valid_o <= valid_i; rdata_o <= rdata_i; - + // check if address is valid if( (valid_i) && (addr_i >= BASE_ADDR) && (addr_i <= BASE_ADDR + {self.max_rel_addr})) begin @@ -199,11 +273,10 @@ always @(posedge clk) begin end end end +""" - """ - - hdl = f"" - return hdl + hdl = declaration + memory_handler_hdl + "endmodule" + return hdl def hdl_top_level_ports(self): probes = [] @@ -212,28 +285,25 @@ always @(posedge clk) begin for input in self.inputs: name = input["name"] width = input["width"] - + if width == 1: probes.append(f"input wire {name}") - + else: probes.append(f"input wire [{width-1}:0] {name}") - # generate outputs + # generate outputs for output in self.outputs: name = output["name"] width = output["width"] if width == 1: probes.append(f"output reg {name}") - + else: probes.append(f"output reg [{width-1}:0] {name}") - - print(probes) - hdl = f"" - return hdl + return probes class LUTRAMCore: def __init__(self, config, interface): @@ -241,7 +311,7 @@ class LUTRAMCore: assert "size" in config, "Size not specified for LUT RAM core." self.size = config["size"] - + def hdl_inst(self): hdl = f""" lut_ram #(.DEPTH({self.size})) {self.name} ( @@ -258,7 +328,7 @@ class LUTRAMCore: .rdata_o(), .rw_o(), .valid_o());\n""" - + return hdl def hdl_def(self): @@ -292,13 +362,13 @@ class LogicAnalyzerCore: assert "triggers" in config, "No triggers found." assert len(config["triggers"]) > 0, "Must specify at least one trigger." self.triggers = config["triggers"] - + def hdl_inst(self): ports = [] ports = [f".{name}({name})," for name in self.probes.keys()] ports = "\n\t\t".join(ports) - + hdl = f""" la_core {self.name} ( .clk(clk), @@ -310,13 +380,13 @@ class LogicAnalyzerCore: .valid_i(), {ports} - + .addr_o(), .wdata_o(), .rdata_o(), .rw_o(), .valid_o());\n""" - + return hdl def run(self): @@ -428,14 +498,14 @@ class LogicAnalyzerCore: def hdl_top_level_ports(self): # this should return the probes that we want to connect to top-level, but as a list of verilog ports - + ports = [] for name, width in self.probes.items(): if width == 1: ports.append(f"input wire {name}") else: ports.append(f"input wire [{width-1}:0] {name}") - + return ports class Manta: @@ -466,7 +536,7 @@ class Manta: elif core["type"] == "io": new_core = IOCore(core, self.interface) - + elif core["type"] == "lut_ram": new_core = LUTRAMCore(core, self.interface) @@ -506,7 +576,7 @@ class Manta: # make pairwise cores core_pairs = [(self.cores[i - 1], self.cores[i]) for i in range(1, len(self.cores))] - + conns = [] for core_pair in core_pairs: src = core_pair[0].name @@ -518,7 +588,7 @@ class Manta: hdl += f"\treg {src}_{dst}_rw;\n" hdl += f"\treg {src}_{dst}_valid;\n" conns.append(hdl) - + return conns def generate_instances(self): @@ -537,20 +607,20 @@ class Manta: else: src_name = self.cores[i-1].name hdl = hdl.replace(".rdata_i()", f".rdata_i({src_name}_{core.name}_rdata)") - + hdl = hdl.replace(".addr_i()", f".addr_i({src_name}_{core.name}_addr)") hdl = hdl.replace(".wdata_i()", f".wdata_i({src_name}_{core.name}_wdata)") hdl = hdl.replace(".rw_i()", f".rw_i({src_name}_{core.name}_rw)") hdl = hdl.replace(".valid_i()", f".valid_i({src_name}_{core.name}_valid)") - - - # connect output + + + # connect output if (i < len(self.cores)-1): dst_name = self.cores[i+1] hdl = hdl.replace(".addr_o()", f".addr_o({core.name}_{dst_name}_addr)") hdl = hdl.replace(".wdata_o()", f".wdata_o({core.name}_{dst_name}_wdata)") - + else: dst_name = "btx" @@ -559,7 +629,7 @@ class Manta: hdl = hdl.replace(".valid_o()", f".valid_o({core.name}_{dst_name}_valid)") insts.append(hdl) - + return insts def generate_core_chain(self): @@ -571,7 +641,7 @@ class Manta: if (i != len(insts)-1): core_chain.append(conns[i]) - + return '\n'.join(core_chain) def generate_header(self): @@ -603,7 +673,7 @@ Provided under a GNU GPLv3 license. Go wild. ports = [f" {port},\n" for port in core.hdl_top_level_ports()] ports = "".join(ports) core_chain_ports.append(ports) - + core_chain_ports = "\n".join(core_chain_ports) ports = interface_ports + core_chain_ports @@ -613,8 +683,6 @@ Provided under a GNU GPLv3 license. Go wild. if ports[-1] == ",": ports = ports[:-1] - print(ports) - return f""" module manta ( input wire clk, @@ -637,7 +705,7 @@ module manta ( reg [15:0] brx_{self.cores[0].name}_wdata; reg brx_{self.cores[0].name}_rw; reg brx_{self.cores[0].name}_valid;\n""" - + return interface_rx_inst + interface_rx_conn def generate_interface_tx(self): @@ -655,12 +723,12 @@ module manta ( interface_tx_inst = interface_tx_inst.replace("rdata_i()", f"rdata_i({self.cores[0].name}_btx_rdata)") interface_tx_inst = interface_tx_inst.replace("rw_i()", f"rw_i({self.cores[0].name}_btx_rw)") interface_tx_inst = interface_tx_inst.replace("valid_i()", f"valid_i({self.cores[0].name}_btx_valid)") - + return interface_tx_conn + interface_tx_inst def generate_footer(self): - return """endmodule\n""" - + return """endmodule\n""" + def generate_module_defs(self): # aggregate module definitions and remove duplicates module_defs_with_dups = [self.interface.rx_hdl_def()] + [core.hdl_def() for core in self.cores] + [self.interface.tx_hdl_def()] @@ -673,22 +741,22 @@ module manta ( def generate_hdl(self, output_filepath): """ This function generates manta.v, which has the following anatomy: - - Header - contains a little blurb about when and who generated the file + - Header - contains a little blurb about when and who generated the file - Top-Level Module - the actual definition of module manta - - Declaration - contains `module manta` and top-level ports + - Declaration - contains `module manta` and top-level ports that constitutent cores need access to - Interface RX - the modules needed to bring whatever interface the user selected onto the bus. For UART, this is just an instance of uart_rx and bridge_rx. - Core Chain - the chain of cores specified by the user. This follows a sequence of: - - Core Instance - HDL specifying an instance of the core. + - Core Instance - HDL specifying an instance of the core. - Core Connection - HDL specifying the registers that connect one core to the next. - - Core Instance + - Core Instance - Core Connection .... - + This repeats for however many cores the user specified. - Interface TX - the modules needed to bring the bus out to whatever @@ -697,7 +765,7 @@ module manta ( - Footer - just the 'endmodule' keyword. - Module Definitions - all the source for the modules instantiated in the - top-level module. + top-level module. """ # generate header @@ -707,11 +775,11 @@ module manta ( declar = self.generate_declaration() # generate interface_rx - interface_rx = self.generate_interface_rx() - - # generate core chain + interface_rx = self.generate_interface_rx() + + # generate core chain core_chain = self.generate_core_chain() - + # generate interface_tx interface_tx = self.generate_interface_tx() @@ -720,7 +788,7 @@ module manta ( # generate module definitions module_defs = self.generate_module_defs() - + # assemble all the parts hdl = header + declar + interface_rx + core_chain + interface_tx + footer hdl += "\n /* ---- Module Definitions ---- */\n" @@ -734,7 +802,7 @@ module manta ( hdl = "`default_nettype none\n" + "`timescale 1ns/1ps\n" + hdl + "`default_nettype wire" with open(output_filepath, 'w') as f: - f.write(hdl) + f.write(hdl) def main():