Merge https://github.com/efabless/caravel into main
diff --git a/LICENSE-2.0 b/LICENSE-2.0
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/LICENSE-2.0
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/README_MORPHLE_LOGIC.md b/README_MORPHLE_LOGIC.md
new file mode 100644
index 0000000..019b88d
--- /dev/null
+++ b/README_MORPHLE_LOGIC.md
@@ -0,0 +1,103 @@
+# Morphle Logic
+
+The most well known reconfigurable hardware systems are the FPGAs (Field Programmable Logic Arrays) and the CPLDs (Complex Programmable Logic Devices). Though currently the two terms are a bit fuzzy for low end devices, originally FPGAs had an architecture with islands of configurable logic, normally small LUTs (lookup tables), connected via a static routing fabric with circuits not that different from early telephone switching hubs. CPLDs, on the other hand, evolved from PALs (Programmable Arrays Logic) with an OR of ANDs architectures. CPLDs are like a small number of PALs connected inside a single chip.
+
+Morphle Logic represents an alternative in the design space of reconfigurable hardware. Like the two options, it has its advantages and limitations. The main advantages are the simple integration with software systems and the ease of generating new configurations at runtime.
+
+## Key Concepts
+
+At the most basic level, Morphle Logic is a large 2D matrix of simple cells. Each cell is connected to the one above, below, to the left and to the right of it.
+
+### Cell Configuration
+
+Each cell can be configured to one of eight values, which we represent with a character:
+
+ 0. space: the default state, it is used to isolate different circuits
+ 1. +: this allows signals to cross this cell vertically and horizontally without interfering with each other
+ 2. -: this allows signals to cross this cell horizontally
+ 3. |: this allows signals to cross this cell vertically
+ 4. 1: when the vertical input is 1, the horizontal output is set to 1
+ 5. 0: when the vertical input is 0, the horizontal output is set to 1
+ 6. Y: when the horizontal input is 1, the vertical output is set to 1
+ 7. N: when the horizontal input is 0, the vertical output is set to 0
+
+An alternative name for Morphle Logic would be "match logic" since you explicitly list the values that you want the inputs to match.
+
+Here is an example of a two bit half adder:
+
+ ||
+ 00N
+ 11NY
+ ||
+
+The first and last lines use | to make it easier to see where the two inputs are coming in from the top and the two outputs (sum and carry, respectively) are going out the bottom. In a real circuit they probably wouldn't be needed as you can normally connect two circuits by just placing them next to each other.
+
+The 11 forms a two input AND gate, while the 00 is a two input NOR gate (AND with the inputs inverted). It is easier to understand in terms of matching the inputs, as mentioned above. The vertical NN is exactly the same as 00 but rotated 90 degrees. So it too is a NOR gate. The means that the sum is 1 if we don't see a 00 input and we don't see a 11 input, which is a XOR (exclusive OR). The Y is a vertical one input AND gate, which is just a buffer repeating a horizontal signal to a vertical one. If we prefer the carry to be horizontal then the Y is not needed.
+
+### Asynchronous Operation
+
+The the horizontal and vertical signals going through each cell can have three values: 1, 0 and empty. A group of cells only operate when all of their outputs are empty and all of their inputs have actual values. After the operation the outputs will have values and the inputs will be empty.
+
+One way to think of ML operation is that waves of data values flow through the circuit. An alternative way is to think that waves of empty values flow backwards through the circuit (a bit like electrons and holes in semiconductors). If a wave of data arrives at a part of the circuit that doesn't have empty outputs, it must wait in place until they become empty. This means that there is no separation of sequential logic and combinational logic like in synchronous circuits.
+
+ML works fastest when alternating valid and empty data flows through the circuit. If some output stalls, then next waves of data stop behind it just like cars stopping at a red light squeeze out the same between them. When the output does become free the waves start to move again and tend to spread out.
+
+### Network
+
+Two ML circuits are connected by placing them next to each other and having them touch, or else using a few "-" or "|" cells to bridge the small space between them.
+
+It would be possible, but very slow, to connect very distant circuits this way. A better way is to use a packet switching network to link didtant circuits, in contrast to the circuit switching fabric of FPGAs (though extremely recent FPGAs have added packet switching).
+
+Packets of data through a network look just like waves of data through a ML circuit, so there is no mismatch when converting between one and the other.
+
+Instead of having every ML cell connect to the network, a row of special cells is inserted between some of the normal rows (between every 8 normal rows, for example). These cells also have eight possible configurations:
+
+ 0. space: the default state, it is used to isolate the row above from the one in the row below
+ 1. a: this receives a bit from the first network port
+ 2. b: this receives a bit from the second network port
+ 3. c: this receives a bit from the third network port
+ 4. |: this connects a cell from the row above to a cell in the row below
+ 5. r: this outputs a bit to the first network port
+ 6. s: this outputs a bit to the second network port
+ 7. t: this outputs a bit to the third network port
+
+A two bit full adder could receive its data from the network are return its results to the network:
+
+ ab ab
+ 00N 00N
+ 11NN 11NN
+ || ||
+ 0N0| 0N0|
+ 1N1N 1N1N
+ || 0-Y| |
+ || | |
+ || | |
+ cs s t
+
+Note that rows and columns can easily be swapped to help match the outputs of a circuit to the inputs of the next circuit.
+
+The first row and the last row are network ports while the 8 middle rows are normal ML cells. Two bits from an incoming packet are placed in the columns labelled "a" and two bits from a different packet are sent to columns "b". A single bit from a third packet goes into the bottom of the columns labelled "c". There is no conflict between that and the first "a" because of a space cell in that column. A and B are the values to be added and C is the carry in.
+
+The two bits from the addition appear in the columns labelled "s" and exit the bottom into the network as one packet. The carry out is a separate one bit packet read from the column labelled "t".
+
+The network protocol is very simple. A row and column address select a starting point and a size field indicates how many columns will receive the packet. The row address only takes into account the special rows with networking hardware. In the adder example above the row with the "a" and "b" would be address 0 and the one with "c", "s" and "t" would be row 1.
+
+The column address and packet size might be restricted to a multiple of some value, like 8. This means that the lowest three bits of the column address and of the size would be ignored in this case.
+
+The following packet types are used:
+
+ 0. configure: the following bytes are shifted into the configuration registers of the rows below
+ 1. a: the following bytes supply the bits for the "a" inputs
+ 2. b: the following bytes supply the bits for the "b" inputs
+ 3. c: the following bytes supply the bits for the "c" inputs
+ 4. run: at the start of a configuration all lines and columns are forced to empty. This packet allows the circuit to function normally
+ 5. r: the following bytes are to be used as the header for any packets with bits from the "r" outputs
+ 6. s: the following bytes are to be used as the header for any packets with bits from the "s" outputs
+ 7. t: the following bytes are to be used as the header for any packets with bits from the "t" outputs
+
+## Files
+
+Besides all the files in the Caravel project, the Morphle Logic specific hardware description can
+be found in "verilog/morphle/" and that includes all tests.
+
+
diff --git a/_config.yml b/_config.yml
new file mode 100644
index 0000000..3397c9a
--- /dev/null
+++ b/_config.yml
@@ -0,0 +1 @@
+theme: jekyll-theme-architect
\ No newline at end of file
diff --git a/verilog/morphle/README.md b/verilog/morphle/README.md
new file mode 100644
index 0000000..4b223d1
--- /dev/null
+++ b/verilog/morphle/README.md
@@ -0,0 +1,32 @@
+# Tests
+
+Each circuit in this directory is a top level simulation-only device which tests the components found in the ../verilog directory.
+
+The way to execute them is
+
+ iverilog testNNNdescription.v
+ vvp a.out
+
+Normally some output is printed or a .vcd file is generated which can then be examined with gtkwave.
+
+### test001ycfsm.v
+
+This puts the asynchronous finite state machine inside the basic Morphle Logic cell through its paces and prints out values from the tester and several internal signals of the fsm module. The use of internal signals helped debug the initial design, but might break this test if that design is changed in the future.
+
+Many signals are two bit busses and can have the values 0 (indicating "empty"), 1 (indicating a logical 0) or 2 (indicating a logica 1). Some internal signals can be temporarily 3 but that normally shouldn't appear.
+
+### test002ycfsm.v
+
+This is the finite state machine being tested by this and the previous test. The expected output value is indicated by the color inside each circle representing the states. The input values are indicated by the color of the arrows, which can be hard to see due to the red stripes.
+
+![Finite State Machine for basic Morphle Logic cell](ycfsmnum.png)
+
+A separate file, "test002.tv", has the actual test vectors with one 7 bit vector per line. The reset signal is a single bit but all others are pairs with 00 indicating "empty", 01 indicating a logical 0 and 10 a logical 1. The last two bits are the expected value for the output and an error is printed if that is not what comes out of the actual circuit.
+
+Since no internal signals are used, this test should work even if the circuit is changed as long as it still implements the fsm indicated above. In order to check that all transitions (arrows) are tested they were numbered and the test vector file has comments indicating where each transitions is tested for the first time. In order to get to a transition that hasn't yet been tested it is often necessary to go through many that have already been seen. That is the big problem with black box testing and why it is a good idea to include BIST (built-in self test circuits) in a design.
+
+### test003ycconfig.v
+
+This tests the configuration circuit by manually shifting in 3 bits at a time and listing the outputs. It adds a comment about which state the configuration is in after the 3 bits.
+
+A second configuration circuit is cascaded with the first in this test. Every time the first circuit has a valid configuration, the second one should have the previous valid configuration of the first circuit.
diff --git a/verilog/morphle/morphlelogic.v b/verilog/morphle/morphlelogic.v
new file mode 100644
index 0000000..ca94415
--- /dev/null
+++ b/verilog/morphle/morphlelogic.v
@@ -0,0 +1,300 @@
+// Copyright 2020 Jecel Mattos de Assumpcao Jr
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+// These are the building blocks for Morphle Logic, an asynchronous
+// runtime reconfigurable array (ARRA).
+
+// many signals are two bit busses
+`define Vempty 0
+`define V0 1
+`define V1 2
+// the combination 3 is not defined
+
+// this asynchronous finite state machine is the basic building block
+// of Morphle Logic. It explicitly defines 5 simple latches that
+// directly change when their inputs do, so there is no clock anywhere
+
+module ycfsm (reset, in, match, out);
+ input reset;
+ input [1:0] in;
+ input [1:0] match;
+ output [1:0] out;
+
+ wire [1:0] lin;
+ wire [1:0] nlin;
+ wire [1:0] lmatch;
+ wire [1:0] nlmatch;
+ wire lmempty;
+ wire nlmempty;
+
+ wire linval = lin != `Vempty;
+ wire inval = in != `Vempty;
+ wire lmatchval = lmatch != `Vempty;
+ wire matchval = match != `Vempty;
+
+ wire clear = reset | (lmempty & linval & ~inval);
+ wire [1:0] clear2 = {clear,clear};
+
+ // two bit latches
+ assign lin = ~(clear2 | nlin);
+ assign nlin = ~(in | lin);
+
+ assign lmatch = ~(clear2 | nlmatch);
+ assign nlmatch = ~((match & {nlmempty,nlmempty}) | lmatch);
+
+ // one bit latch
+ assign lmempty = ~(~(linval | lmatchval) | nlmempty);
+ assign nlmempty = ~((lmatchval & ~matchval) | lmempty);
+
+ // forward the result of combining match and in
+ assign out[1] = lin[1] & lmatch[1];
+ assign out[0] = (lmatch[1] & lin[0]) | (lmatch[0] & linval);
+
+endmodule
+
+// each "yellow cell" in Morphle Logic can be configured to one of eight
+// different options. This circuit saves the 3 bits of the configuration
+// and outputs the control circuit the rest of the cell needs
+//
+// the case statement is where the meaning of the configuration bits are
+// defined and is the only thing that needs to change (not counting software)
+// if the meaning needs to be changed
+
+module ycconfig (confclk, cbitin, cbitout,
+ empty,
+ hblock, hbypass, hmatch0, hmatch1,
+ vblock, vbypass, vmatch0, vmatch1);
+ input confclk, cbitin;
+ output cbitout;
+ output empty;
+ output hblock, hbypass, hmatch0, hmatch1;
+ output vblock, vbypass, vmatch0, vmatch1;
+ reg [8:0] r; // case needs REG even though we want a combinational circuit
+ assign {empty,hblock,hbypass, hmatch0, hmatch1,
+ vblock, vbypass, vmatch0, vmatch1} = r;
+
+ reg [2:0] cnfg;
+ always @(posedge confclk) cnfg = {cnfg[1:0],cbitin}; // shift to msb
+ assign cbitout = cnfg[2]; // shifted to next cell
+
+ always @*
+ case(cnfg)
+ 3'b000: r = 9'b110001000; // space is empty and blocked
+ 3'b001: r = 9'b000110011; // + sync with don't cares
+ 3'b010: r = 9'b001001000; // - horizontal short circuit
+ 3'b011: r = 9'b010000100; // | vertical short circuit
+ 3'b100: r = 9'b000110001; // 1 1 vertical, X horizontal
+ 3'b101: r = 9'b000110010; // 0 0 vertical, X horizontal
+ 3'b110: r = 9'b000010011; // Y X vertical, 1 horizontal
+ 3'b111: r = 9'b000100011; // N X vertical, 0 horizontal
+ endcase
+
+endmodule
+
+// this is the heart of Morphle Logic. It is called the "yellow cell" because
+// of the first few illustrations of how it would work, with "red cells" being
+// where the inputs and outputs connect to the network. Each yellow cell
+// connects to four neighbors, labelled U (up), D (down), L (left) and R (right)
+//
+// Each cell receives its configuration bits from U and passes them on to D
+//
+// Values are indicated by a pair of wires, where 00 indicates empty, 01 a
+// 0 value and 10 indicates a 1 value. The combination 11 should never appear
+//
+// Vertical signals are implemented by a pair of pairs, one of which goes
+// from U to D and the second goes D to U. The first pair is the accumulated
+// partial results from several cells while the second is the final result
+// Horizontal signals also have a L to R pair for partial results and a R to L
+// pair for final results
+
+module ycell(reset, confclk, cbitin, cbitout,
+ hempty, vempty,
+ uempty, uin, uout,
+ dempty, din, dout,
+ lempty, lin, lout,
+ rempty, rin, rout);
+ // control
+ input reset; // freezes the cell operations and clears everything
+ input confclk; // a strobe to enter one configuration bit
+ input cbitin; // new configuration bit from previous cell (U)
+ output cbitout; // configuration bit to next cell (D)
+ output hempty; // this cell interrupts horizontal signals
+ output vempty; // this cell interrupts vertical signals
+ // UP
+ input uempty; // cell U is empty, so we are the topmost of a signal
+ input [1:0] uin;
+ output [1:0] uout;
+ // DOWN
+ input dempty; // cell D is empty, so we are the bottommost of a signal
+ input [1:0] din;
+ output [1:0] dout;
+ // LEFT
+ input lempty; // cell L is empty, so we are the leftmost of a signal
+ input [1:0] lin;
+ output [1:0] lout;
+ // RIGHT
+ input rempty; // cell D is empty, so we are the rightmost of a signal
+ input [1:0] rin;
+ output [1:0] rout;
+
+ // configuration signals decoded
+ wire empty;
+ wire hblock, hbypass, hmatch0, hmatch1;
+ wire vblock, vbypass, vmatch0, vmatch1;
+ ycconfig cfg (confclk, cbitin, cbitout,
+ empty,
+ hblock, hbypass, hmatch0, hmatch1,
+ vblock, vbypass, vmatch0, vmatch1);
+
+ assign hempty = empty | hblock;
+ assign vempty = empty | vblock;
+ wire hreset = reset | hblock; // perhaps "| hbypass" to save energy?
+ wire vreset = reset | vblock;
+
+ // internal wiring
+ wire [1:0] vin;
+ wire [1:0] vout;
+ wire [1:0] vback;
+ wire [1:0] hin;
+ wire [1:0] hout;
+ wire [1:0] hback;
+
+ wire [1:0] hmatch = {vback[1]&hmatch1,vback[0]&hmatch0};
+ ycfsm hfsm (hreset, hin, hmatch, hout);
+ wire [1:0] bhout = hbypass ? hin : hout;
+ assign rout = bhout;
+ assign hin = lempty ? {~(hback[1]|hback[1'b0]),1'b0} : lin;
+ assign hback = rempty ? bhout : rin;
+ assign lout = hback;
+
+ wire [1:0] vmatch = {hback[1]&vmatch1,hback[0]&vmatch0};
+ ycfsm vfsm (vreset, vin, vmatch, vout);
+ wire [1:0] bvout = vbypass ? vin : vout;
+ assign dout = bvout;
+ assign vin = uempty ? {~(vback[1]|vback[1'b0]),1'b0} : uin;
+ assign vback = dempty ? bvout : din;
+ assign uout = vback;
+
+endmodule
+
+module yblock(reset, confclk, cbitin, cbitout,
+ lhempty, uvempty,
+ rhempty, dvempty,
+ uempty, uin, uout,
+ dempty, din, dout,
+ lempty, lin, lout,
+ rempty, rin, rout);
+ parameter BLOCKWIDTH = 8;
+ parameter BLOCKHEIGHT = 8;
+ parameter HMSB = BLOCKWIDTH-1;
+ parameter HMSB2 = (2*BLOCKWIDTH)-1;
+ parameter VMSB = BLOCKHEIGHT-1;
+ parameter VMSB2 = (2*BLOCKHEIGHT)-1;
+ // control
+ input reset; // freezes the cell operations and clears everything
+ input confclk; // a strobe to enter one configuration bit
+ input [HMSB:0] cbitin; // new configuration bit from previous cell (U)
+ output [HMSB:0] cbitout; // configuration bit to next cell (D)
+ output [HMSB:0] lhempty; // this cell interrupts horizontal signals to left
+ output [HMSB:0] uvempty; // this cell interrupts vertical signals to up
+ output [HMSB:0] rhempty; // this cell interrupts horizontal signals to right
+ output [HMSB:0] dvempty; // this cell interrupts vertical signals to down
+ // UP
+ input [HMSB:0] uempty; // cell U is empty, so we are the topmost of a signal
+ input [HMSB2:0] uin;
+ output [HMSB2:0] uout;
+ // DOWN
+ input [HMSB:0] dempty; // cell D is empty, so we are the bottommost of a signal
+ input [HMSB2:0] din;
+ output [HMSB2:0] dout;
+ // LEFT
+ input [VMSB:0] lempty; // cell L is empty, so we are the leftmost of a signal
+ input [VMSB2:0] lin;
+ output [VMSB2:0] lout;
+ // RIGHT
+ input [VMSB:0] rempty; // cell D is empty, so we are the rightmost of a signal
+ input [VMSB2:0] rin;
+ output [VMSB2:0] rout;
+
+ // vertical lines are row order, horizontal lines are column order
+ // this makes assigns chunks much simpler
+
+ wire [((BLOCKWIDTH*(BLOCKHEIGHT+1))-1):0] vcbit;
+ wire [((BLOCKWIDTH*(BLOCKHEIGHT+2))-1):0] ve; // first and last rows go outside
+ wire [(((BLOCKWIDTH+2)*BLOCKHEIGHT)-1):0] he; // first and last columns go outside
+ wire [(((BLOCKWIDTH*2)*(BLOCKHEIGHT+1))-1):0] vs; // signal pairs
+ wire [(((BLOCKWIDTH*2)*(BLOCKHEIGHT+1))-1):0] vb; // signal pairs back
+ wire [(((BLOCKWIDTH+1)*(BLOCKHEIGHT*2))-1):0] hs; // signal pairs
+ wire [(((BLOCKWIDTH+1)*(BLOCKHEIGHT*2))-1):0] hb; // signal pairs back
+
+ genvar x;
+ genvar y;
+
+ generate
+ for (x = 0 ; x < BLOCKWIDTH ; x = x + 1) begin
+ for (y = 0 ; y < BLOCKHEIGHT ; y = y + 1) begin
+ ycell gencell (reset, confclk,
+ // cbitin, cbitout,
+ vcbit[x+(y*BLOCKWIDTH)], vcbit[x+((y+1)*BLOCKWIDTH)],
+ // hempty, vempty,
+ he[y+((x+1)*BLOCKHEIGHT)], ve[x+((y+1)*BLOCKWIDTH)],
+ // uempty, uin, uout,
+ ve[x+(y*BLOCKWIDTH)],
+ vs[(2*x)+1+(y*2*BLOCKWIDTH):(2*x)+(y*2*BLOCKWIDTH)],
+ vb[(2*x)+1+(y*2*BLOCKWIDTH):(2*x)+(y*2*BLOCKWIDTH)],
+ // dempty, din, dout,
+ ve[x+((y+2)*BLOCKWIDTH)],
+ vs[(2*x)+1+((y+1)*2*BLOCKWIDTH):(2*x)+((y+1)*2*BLOCKWIDTH)],
+ vb[(2*x)+1+((y+1)*2*BLOCKWIDTH):(2*x)+((y+1)*2*BLOCKWIDTH)],
+ // lempty, lin, lout,
+ he[y+(x*BLOCKHEIGHT)],
+ hs[(2*y)+1+(x*2*BLOCKHEIGHT):(2*y)+(x*2*BLOCKHEIGHT)],
+ hb[(2*y)+1+(x*2*BLOCKHEIGHT):(2*y)+(x*2*BLOCKHEIGHT)],
+ // rempty, rin, rout
+ he[y+((x+2)*BLOCKHEIGHT)],
+ hs[(2*y)+1+((x+1)*2*BLOCKHEIGHT):(2*y)+((x+1)*2*BLOCKHEIGHT)],
+ hb[(2*y)+1+((x+1)*2*BLOCKHEIGHT):(2*y)+((x+1)*2*BLOCKHEIGHT)]
+ );
+ end
+ end
+ endgenerate
+
+ // the ends of the arrays of wire go to the outside
+
+ assign vcbit[BLOCKWIDTH-1:0] = cbitin;
+ assign cbitout = vcbit[((BLOCKWIDTH*(BLOCKHEIGHT+1))-1):BLOCKWIDTH*BLOCKHEIGHT];
+ assign lhempty = he[BLOCKWIDTH+BLOCKHEIGHT-1:BLOCKWIDTH];
+ assign uvempty = ve[BLOCKWIDTH-1+BLOCKHEIGHT:BLOCKHEIGHT];
+ assign rhempty = he[(((BLOCKWIDTH+1)*BLOCKHEIGHT)-1):BLOCKWIDTH*BLOCKHEIGHT];
+ assign dvempty = ve[((BLOCKWIDTH*(BLOCKHEIGHT+1))-1):BLOCKWIDTH*BLOCKHEIGHT];
+ // UP
+ assign ve[BLOCKWIDTH-1:0] = uempty;
+ assign vs[(2*BLOCKWIDTH)-1:0] = uin;
+ assign uout = vb[(2*BLOCKWIDTH)-1:0];
+ // DOWN
+ assign ve[((BLOCKWIDTH*(BLOCKHEIGHT+2))-1):BLOCKWIDTH*(BLOCKHEIGHT+1)] = dempty;
+ assign vb[(((BLOCKWIDTH*2)*(BLOCKHEIGHT+1))-1):BLOCKWIDTH*2*BLOCKHEIGHT] = din;
+ assign dout = vs[(((BLOCKWIDTH*2)*(BLOCKHEIGHT+1))-1):BLOCKWIDTH*2*BLOCKHEIGHT];
+ // LEFT
+ assign he[BLOCKHEIGHT-1:0] = lempty;
+ assign hs[(2*BLOCKHEIGHT)-1:0] = lin;
+ assign lout = hb[(2*BLOCKHEIGHT)-1:0];
+ // RIGHT
+ assign he[(((BLOCKWIDTH+2)*BLOCKHEIGHT)-1):(BLOCKWIDTH+1)*BLOCKHEIGHT] = rempty;
+ assign hb[(((BLOCKWIDTH+1)*(BLOCKHEIGHT*2))-1):BLOCKWIDTH*BLOCKHEIGHT*2] = rin;
+ assign rout = hs[(((BLOCKWIDTH+1)*(BLOCKHEIGHT*2))-1):BLOCKWIDTH*BLOCKHEIGHT*2];
+
+endmodule
+
diff --git a/verilog/morphle/test001ycfsm.v b/verilog/morphle/test001ycfsm.v
new file mode 100644
index 0000000..880e915
--- /dev/null
+++ b/verilog/morphle/test001ycfsm.v
@@ -0,0 +1,62 @@
+// Copyright 2020 Jecel Mattos de Assumpcao Jr
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// simple test for the basic finite state machine for Morphle Logic
+// this lists many internal variables in order to find a bug in the
+// reset logic, so it isn't a proper black box test. It is also an
+// experiement in generating a waveform file
+
+`timescale 1ns/1ps
+`include "morphlelogic.v"
+
+module test1fsm;
+
+ reg [1:0] in;
+ wire [1:0] out;
+ reg reset;
+ reg [1:0] match;
+
+ ycfsm DUT (reset, in, match, out);
+
+ initial
+ begin
+ reset = 0; in = `Vempty; match = `Vempty;
+ #10 reset = 1;
+ #10 reset = 0;
+ #10 in = `V1;
+ #10 match = `V1;
+ #10 match = `Vempty;
+ #10 in = `Vempty;
+ #10 match = `V0;
+ #10 match = `Vempty;
+ #10 in = `V1;
+ #10 match = `V1;
+ #10 in = `Vempty;
+ #10 in = `V0;
+ #10 match = `Vempty;
+ #10 in = `Vempty;
+ #10;
+ end
+
+ initial
+ begin
+ $monitor($time,,reset,out,,
+ in,DUT.lin,DUT.nlin,DUT.inval,DUT.linval,,
+ match,DUT.lmatch,DUT.nlmatch,DUT.matchval,DUT.lmatchval,,
+ DUT.clear2,DUT.lmempty,DUT.nlmempty);
+ $dumpfile("test.vcd");
+ $dumpvars;
+ end
+
+endmodule
diff --git a/verilog/morphle/test002.tv b/verilog/morphle/test002.tv
new file mode 100644
index 0000000..99310a6
--- /dev/null
+++ b/verilog/morphle/test002.tv
@@ -0,0 +1,105 @@
+// Copyright 2020 Jecel Mattos de Assumpcao Jr
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// test vectors for basic Morphle Logic block finite state machine
+// to be used with test002ycfsm.v
+//
+// each vector in the the format reset_in_match_out
+//
+// where 00 indicates "empty", "01" indicates a 0 value and "10 a 1 value
+//
+// The goal is to test each "arrow" in the picture of the FSM
+// There are 35 valid transitions and we number them from top to
+// bottom, left to right. The number of a transition is indicated in
+// square brackets in the comment of a vector, with an * indicating
+// that this is the first occurance of that transitions (it might
+// have to be used again to test some other transition later)
+
+0_00_00_00 // first two vectors have the output ignored to settle down
+1_00_00_00 // reset everything [1]*
+1_00_00_00 // keep it in reset a little longer
+0_00_00_00
+0_10_00_00 // first input [2]*
+0_10_10_10 // with a match [6]*
+0_10_00_10 // remember the match [17]*
+0_00_00_00 // back to start [22]*
+0_00_01_00 // mismatch [5]*
+0_00_00_00 // remembered [15]*
+0_10_00_01 // late input [28]*
+0_10_10_01 // next match - no transition
+0_00_10_00 // back to start and deal with match [23]*[4]*
+0_01_10_01 // input [11]*
+0_01_00_01 // remember match [19]*
+0_00_00_00 // back to start [23]
+0_01_00_00 // [3]*
+0_01_10_01 // [8]*
+0_00_10_01 // [18]*
+0_00_00_00 // [21]*
+0_10_00_00 // [2]
+0_10_01_01 // [7]*
+0_00_01_01 // [18]
+0_00_00_00 // [21]
+0_01_00_00 // [3]
+0_01_01_01 // [9]*
+0_01_00_01 // [19]
+0_00_00_00 // [23]
+0_00_10_00 // [4]
+0_10_10_10 // [10]*
+0_00_10_10 // [16]*
+0_00_00_00 // [20]*
+0_00_10_00 // [4]
+0_00_00_00 // [12]*
+0_10_00_10 // [24]*
+0_00_00_00 // [22]
+0_00_10_00 // [4]
+0_00_00_00 // [12]
+0_01_00_01 // [25]*
+0_00_00_00 // [22]
+0_00_10_00 // [4]
+0_00_00_00 // [12]
+0_00_10_00 // [26]*
+0_01_10_01 // [32]*
+0_00_10_00 // [23][4]
+0_00_00_00 // [12]
+0_00_01_00 // [27]*
+0_10_01_10 // [33]*
+0_00_01_00 // [22][5]
+0_10_01_01 // [13]*
+0_00_01_01 // [18]
+0_00_00_00 // [21]
+0_00_01_00 // [5]
+0_01_01_01 // [14]*
+0_00_01_01 // [18]
+0_00_00_00 // [21]
+0_00_01_00 // [5]
+0_00_00_00 // [15]
+0_01_00_01 // [29]*
+0_00_00_00 // [23]
+0_00_01_00 // [5]
+0_00_00_00 // [15]
+0_00_10_00 // [30]*
+0_01_10_01 // [34]*
+0_00_10_00 // [23][4]
+0_10_10_10 // [10]
+0_00_10_10 // [16]
+0_00_00_00 // [20]
+0_00_01_00 // [5]
+0_00_00_00 // [15]
+0_00_01_00 // [31]*
+0_10_01_01 // [35]*
+0_00_01_00 // [23][5]
+0_10_01_01 // [13]
+0_00_01_01 // [18]
+0_00_00_00 // [21]
+0_00_00_00 // settle
diff --git a/verilog/morphle/test002ycfsm.v b/verilog/morphle/test002ycfsm.v
new file mode 100644
index 0000000..29a830d
--- /dev/null
+++ b/verilog/morphle/test002ycfsm.v
@@ -0,0 +1,81 @@
+// Copyright 2020 Jecel Mattos de Assumpcao Jr
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// a more complete test for the basic finite state machine for Morphle Logic
+// this reads a file with test vectors and it applies it to the device under
+// test (DUT) and checks that the output is expected. Only the inputs and
+// outputs of the device are used, not the internal signals. This allows
+// these to be regression tests that do not depend on internal changes to
+// the DUT.
+
+// this circuit was derived from the one described in
+// https://syssec.ethz.ch/content/dam/ethz/special-interest/infk/inst-infsec/system-security-group-dam/education/Digitaltechnik_14/14_Verilog_Testbenches.pdf
+
+`timescale 1ns/1ps
+`include "morphlelogic.v"
+
+module test002fsm;
+
+ reg [1:0] in;
+ wire [1:0] out;
+ reg [1:0] outexpected;
+ reg reset;
+ reg [1:0] match;
+
+ reg[31:0] vectornum, errors; // bookkeeping variables
+ reg[6:0] testvectors[10000:0];// array of testvectors/
+ reg clk; // DUT is asynchronous, but the test circuit can't be
+ // generate clock
+ always // no sensitivity list, so it always executes
+ begin
+ clk= 1; #5; clk= 0; #5;// 10ns period
+ end
+
+ ycfsm DUT (reset, in, match, out);
+
+ initial
+ begin
+ $readmemb("test002.tv", testvectors); // Read vectors
+ vectornum= 0; errors = 0; // Initialize
+ end
+
+ // apply test vectors on rising edge of clk
+ always @(posedge clk)
+ begin
+ #1; {reset, in, match, outexpected} = testvectors[vectornum];
+ end
+
+ // check results on falling edge of clk
+ always @(negedge clk)
+ begin
+ $display("testing vector %d", vectornum);
+ if (vectornum>1) // skip two entries to settle down
+ begin
+ if (out !== outexpected)
+ begin
+ $display("Error: inputs = %b", {reset, in, match});
+ $display(" outputs = %b (%b exp)",out,outexpected);
+ errors = errors + 1;
+ end
+ end
+ // increment array index and read next testvector
+ vectornum= vectornum+ 1;
+ if (testvectors[vectornum] ===7'bx)
+ begin
+ $display("%d tests completed with %d errors", vectornum, errors);
+ $finish; // End simulation
+ end
+ end
+
+endmodule
diff --git a/verilog/morphle/test003ycconfig.v b/verilog/morphle/test003ycconfig.v
new file mode 100644
index 0000000..2d57703
--- /dev/null
+++ b/verilog/morphle/test003ycconfig.v
@@ -0,0 +1,136 @@
+// Copyright 2020 Jecel Mattos de Assumpcao Jr
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// this tests the configuration circuit for Morphle Logic. For each tests
+// 3 bits have to be shifted into the circuit and then the output is
+// checked for the desired value
+
+`timescale 1ns/1ps
+`include "morphlelogic.v"
+
+module test1fsm;
+
+ reg confclk, cbitin;
+ wire cbitout;
+ wire empty;
+ wire hblock, hbypass, hmatch0, hmatch1;
+ wire vblock, vbypass, vmatch0, vmatch1;
+
+ ycconfig DUT (confclk, cbitin, cbitout,
+ empty,
+ hblock, hbypass, hmatch0, hmatch1,
+ vblock, vbypass, vmatch0, vmatch1);
+
+ // adds a second device cascade with the main one being tested to
+ // see if the expected timing (always holds the previous configuration
+ // of the first device) is present
+
+ wire cbitout2;
+ wire empty2;
+ wire hblock2, hbypass2, hmatch02, hmatch12;
+ wire vblock2, vbypass2, vmatch02, vmatch12;
+
+ ycconfig DUT2 (confclk, cbitout, cbitout2,
+ empty2,
+ hblock2, hbypass2, hmatch02, hmatch12,
+ vblock2, vbypass2, vmatch02, vmatch12);
+
+ initial
+ begin
+ confclk = 0; cbitin = 0;
+ #10 cbitin = 0; // msb
+ #10 confclk = 1;
+ #10 confclk = 0;
+ #10 cbitin = 0;
+ #10 confclk = 1;
+ #10 confclk = 0;
+ #10 cbitin = 0; // lsb
+ #10 confclk = 1;
+ #10 confclk = 0; $display("configuration = space");
+ #10 cbitin = 0; // msb
+ #10 confclk = 1;
+ #10 confclk = 0;
+ #10 cbitin = 0;
+ #10 confclk = 1;
+ #10 confclk = 0;
+ #10 cbitin = 1; // lsb
+ #10 confclk = 1;
+ #10 confclk = 0; $display("configuration = +");
+ #10 cbitin = 0; // msb
+ #10 confclk = 1;
+ #10 confclk = 0;
+ #10 cbitin = 1;
+ #10 confclk = 1;
+ #10 confclk = 0;
+ #10 cbitin = 0; // lsb
+ #10 confclk = 1;
+ #10 confclk = 0; $display("configuration = -");
+ #10 cbitin = 0; // msb
+ #10 confclk = 1;
+ #10 confclk = 0;
+ #10 cbitin = 1;
+ #10 confclk = 1;
+ #10 confclk = 0;
+ #10 cbitin = 1; // lsb
+ #10 confclk = 1;
+ #10 confclk = 0; $display("configuration = |");
+ #10 cbitin = 1; // msb
+ #10 confclk = 1;
+ #10 confclk = 0;
+ #10 cbitin = 0;
+ #10 confclk = 1;
+ #10 confclk = 0;
+ #10 cbitin = 0; // lsb
+ #10 confclk = 1;
+ #10 confclk = 0; $display("configuration = 1");
+ #10 cbitin = 1; // msb
+ #10 confclk = 1;
+ #10 confclk = 0;
+ #10 cbitin = 0;
+ #10 confclk = 1;
+ #10 confclk = 0;
+ #10 cbitin = 1; // lsb
+ #10 confclk = 1;
+ #10 confclk = 0; $display("configuration = 0");
+ #10 cbitin = 1; // msb
+ #10 confclk = 1;
+ #10 confclk = 0;
+ #10 cbitin = 1;
+ #10 confclk = 1;
+ #10 confclk = 0;
+ #10 cbitin = 0; // lsb
+ #10 confclk = 1;
+ #10 confclk = 0; $display("configuration = Y");
+ #10 cbitin = 1; // msb
+ #10 confclk = 1;
+ #10 confclk = 0;
+ #10 cbitin = 1;
+ #10 confclk = 1;
+ #10 confclk = 0;
+ #10 cbitin = 1; // lsb
+ #10 confclk = 1;
+ #10 confclk = 0; $display("configuration = N");
+ #10;
+ end
+
+ initial
+ $monitor($time,,confclk,cbitin,cbitout,,empty,,
+ hblock, hbypass, hmatch0, hmatch1,,
+ vblock, vbypass, vmatch0, vmatch1,,
+ cbitout2,,empty2,,
+ hblock2, hbypass2, hmatch02, hmatch12,,
+ vblock2, vbypass2, vmatch02, vmatch12);
+
+
+endmodule
diff --git a/verilog/morphle/ycfsmnum.png b/verilog/morphle/ycfsmnum.png
new file mode 100644
index 0000000..d1332ed
--- /dev/null
+++ b/verilog/morphle/ycfsmnum.png
Binary files differ