first step to build from smaller blocks
diff --git a/verilog/morphle/config_block.tcl b/verilog/morphle/config_block.tcl
index 5a19c43..0f00b04 100755
--- a/verilog/morphle/config_block.tcl
+++ b/verilog/morphle/config_block.tcl
@@ -4,19 +4,20 @@
set ::env(VERILOG_FILES) "\
$script_dir/../../verilog/rtl/defines.v \
- $script_dir/../../verilog/morphle/morphlelogic.v \
+ $script_dir/../../verilog/morphle/ycell.v \
+ $script_dir/../../verilog/morphle/yblock.v \
$script_dir/../../verilog/morphle/user_proj_block.v"
set ::env(CLOCK_PORT) "wb_clk_i"
set ::env(CLOCK_NET) "blk.confclk"
-set ::env(CLOCK_PERIOD) "0"
+set ::env(CLOCK_PERIOD) "10"
set ::env(FP_PIN_ORDER_CFG) $script_dir/pin_order.cfg
set ::env(CLOCK_TREE_SYNTH) 0
set ::env(FP_CONTEXT_DEF) $script_dir/../user_project_wrapper/runs/user_project_wrapper/tmp/floorplan/ioPlacer.def.macro_placement.def
set ::env(FP_CONTEXT_LEF) $script_dir/../user_project_wrapper/runs/user_project_wrapper/tmp/merged_unpadded.lef
set ::env(FP_SIZING) absolute
-set ::env(DIE_AREA) "0 0 400 400"
+set ::env(DIE_AREA) "0 0 1000 1000"
set ::env(PL_BASIC_PLACEMENT) 1
-set ::env(PL_TARGET_DENSITY) 0.25
+set ::env(PL_TARGET_DENSITY) 0.65
diff --git a/verilog/morphle/morphlelogic.v b/verilog/morphle/morphlelogic.v
deleted file mode 100644
index 8dddcb9..0000000
--- a/verilog/morphle/morphlelogic.v
+++ /dev/null
@@ -1,312 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2020 Jecel Mattos de Assumpcao Jr
-//
-// SPDX-License-Identifier: Apache-2.0
-//
-// 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; // lin != `Vempty;
- wire inval =| in; // in != `Vempty;
- wire lmatchval =| lmatch; // lmatch != `Vempty;
- wire matchval =| match; // 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 | hempty) ? bhout : rin; // don't propagate when rightmost or empty
- 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 | vempty) ? bvout : din; // don't propagate when bottommost or empty
- 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 assigning chunks much simpler
-
- // ----[]----[]----[]----
- // 0 1 2 3 BLOCKHEIGHT+1 vcbit
- //
- // ====[]====[]====[]====
- // 1,0 3,2 5,4 7,6 (BLOCKHEIGHT+1)*2 hs, hb, vs, vb
- //
- // u [ued] [ued] [ued] d
- // \-----/| \------+|+------/|\----/
- // uv-----+--------/ \-------+-----dv BLOCKHEIGHT+2 he, ve
-
- 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 : generate_columns
- for (y = 0 ; y < BLOCKHEIGHT ; y = y + 1) begin : generate_rows
- 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)],
- vb[(2*x)+1+((y+1)*2*BLOCKWIDTH):(2*x)+((y+1)*2*BLOCKWIDTH)],
- vs[(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)],
- hb[(2*y)+1+((x+1)*2*BLOCKHEIGHT):(2*y)+((x+1)*2*BLOCKHEIGHT)],
- hs[(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];
- // UP
- assign ve[BLOCKWIDTH-1:0] = uempty;
- assign uvempty = ve[(2*BLOCKWIDTH)-1:BLOCKWIDTH];
- 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 dvempty = ve[BLOCKWIDTH-1+BLOCKHEIGHT*BLOCKWIDTH:BLOCKHEIGHT*BLOCKWIDTH];
- 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 lhempty = he[(2*BLOCKHEIGHT)-1:BLOCKHEIGHT];
- 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 rhempty = ve[BLOCKHEIGHT-1+BLOCKHEIGHT*BLOCKWIDTH:BLOCKHEIGHT*BLOCKWIDTH];
- 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
index 0956c5c..585320d 100644
--- a/verilog/morphle/test001ycfsm.v
+++ b/verilog/morphle/test001ycfsm.v
@@ -20,9 +20,9 @@
// experiement in generating a waveform file
`timescale 1ns/1ps
-`include "morphlelogic.v"
+`include "ycell.v"
-module test1fsm;
+module test001fsm;
reg [1:0] in;
wire [1:0] out;
diff --git a/verilog/morphle/test002ycfsm.v b/verilog/morphle/test002ycfsm.v
index 51a97c7..45ed561 100644
--- a/verilog/morphle/test002ycfsm.v
+++ b/verilog/morphle/test002ycfsm.v
@@ -25,7 +25,7 @@
// 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"
+`include "ycell.v"
module test002fsm;
diff --git a/verilog/morphle/test003ycconfig.v b/verilog/morphle/test003ycconfig.v
index 56fd94d..623415f 100644
--- a/verilog/morphle/test003ycconfig.v
+++ b/verilog/morphle/test003ycconfig.v
@@ -19,9 +19,9 @@
// checked for the desired value
`timescale 1ns/1ps
-`include "morphlelogic.v"
+`include "ycell.v"
-module test1fsm;
+module test003config;
reg confclk, cbitin;
wire cbitout;
diff --git a/verilog/morphle/test004ycell.v b/verilog/morphle/test004ycell.v
index e23acad..2066c7b 100644
--- a/verilog/morphle/test004ycell.v
+++ b/verilog/morphle/test004ycell.v
@@ -25,9 +25,9 @@
// 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"
+`include "ycell.v"
-module test002fsm;
+module test004ycell;
// control
reg reset; // freezes the cell operations and clears everything
diff --git a/verilog/morphle/user_proj_block.v b/verilog/morphle/user_proj_block.v
index d7a4db2..68240b5 100644
--- a/verilog/morphle/user_proj_block.v
+++ b/verilog/morphle/user_proj_block.v
@@ -107,13 +107,13 @@
wire [HMSB:0] dvempty; // this cell interrupts vertical signals to down
// UP
- wire [HMSB:0] uempty = {HMSB{1'b0}}; // cell U is empty, so we are the topmost of a signal
+ wire [HMSB:0] uempty = {HMSB{1'b0}}; // cell U is not empty, so the LA is above us
wire [HMSB2:0] uin = la_data_in[95:64];
wire [HMSB2:0] uout;
assign la_data_out[31:0] = uout;
// DOWN
wire [HMSB:0] dempty = {HMSB{1'b1}}; // cell D is empty, so we are the bottommost of a signal
- wire [HMSB2:0] dout;
+ wire [HMSB2:0] dout; // left dangling to avoid loops that confuse the tools
wire [HMSB2:0] din = {HMSB2{1'b0}};
// LEFT
wire [VMSB:0] lempty = {VMSB{1'b1}}; // cell L is empty, so we are the leftmost of a signal
diff --git a/verilog/morphle/yblock.v b/verilog/morphle/yblock.v
new file mode 100644
index 0000000..7b9c5d5
--- /dev/null
+++ b/verilog/morphle/yblock.v
@@ -0,0 +1,148 @@
+// SPDX-FileCopyrightText: Copyright 2020 Jecel Mattos de Assumpcao Jr
+//
+// SPDX-License-Identifier: Apache-2.0
+//
+// 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 uses the building blocks for Morphle Logic, an asynchronous
+// runtime reconfigurable array (ARRA), as found in ycell.v to create
+// a block of yellow cells wired together and with ports to connect
+// to other blocks
+
+// many signals are two bit busses
+`define Vempty 0
+`define V0 1
+`define V1 2
+// the combination 3 is not defined
+
+
+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 assigning chunks much simpler
+
+ // ----[]----[]----[]----
+ // 0 1 2 3 BLOCKHEIGHT+1 vcbit
+ //
+ // ====[]====[]====[]====
+ // 1,0 3,2 5,4 7,6 (BLOCKHEIGHT+1)*2 hs, hb, vs, vb
+ //
+ // u [ued] [ued] [ued] d
+ // \-----/| \------+|+------/|\----/
+ // uv-----+--------/ \-------+-----dv BLOCKHEIGHT+2 he, ve
+
+ 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 : generate_columns
+ for (y = 0 ; y < BLOCKHEIGHT ; y = y + 1) begin : generate_rows
+ 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)],
+ vb[(2*x)+1+((y+1)*2*BLOCKWIDTH):(2*x)+((y+1)*2*BLOCKWIDTH)],
+ vs[(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)],
+ hb[(2*y)+1+((x+1)*2*BLOCKHEIGHT):(2*y)+((x+1)*2*BLOCKHEIGHT)],
+ hs[(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];
+ // UP
+ assign ve[BLOCKWIDTH-1:0] = uempty;
+ assign uvempty = ve[(2*BLOCKWIDTH)-1:BLOCKWIDTH];
+ 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 dvempty = ve[BLOCKWIDTH-1+BLOCKHEIGHT*BLOCKWIDTH:BLOCKHEIGHT*BLOCKWIDTH];
+ 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 lhempty = he[(2*BLOCKHEIGHT)-1:BLOCKHEIGHT];
+ 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 rhempty = ve[BLOCKHEIGHT-1+BLOCKHEIGHT*BLOCKWIDTH:BLOCKHEIGHT*BLOCKWIDTH];
+ 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/ycell.v b/verilog/morphle/ycell.v
new file mode 100644
index 0000000..7ea24ff
--- /dev/null
+++ b/verilog/morphle/ycell.v
@@ -0,0 +1,193 @@
+// SPDX-FileCopyrightText: Copyright 2020 Jecel Mattos de Assumpcao Jr
+//
+// SPDX-License-Identifier: Apache-2.0
+//
+// 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; // lin != `Vempty;
+ wire inval =| in; // in != `Vempty;
+ wire lmatchval =| lmatch; // lmatch != `Vempty;
+ wire matchval =| match; // 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 | hempty) ? bhout : rin; // don't propagate when rightmost or empty
+ 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 | vempty) ? bvout : din; // don't propagate when bottommost or empty
+ assign uout = vback;
+
+endmodule
+