Orangepath/HPRLS Project: Hardware and Embedded Software Synthesis from Executable Specifications.
KiwiC Memory Hazard Example

KiwiC: Memory Hazard Example

Here we show the default method for KiwiC to overcome structural hazards: by splitting conflicted pause blocks into microstates.

More-advanced implementations would schedule resources over multiple blocks to find an optimum schedule.

C# Source Code

```using System;
using System.Text;
using KiwiSystem;

public static class test4
{
static int limit = 10;
[Kiwi.OutputBitPort("dout")] static bool dout;
[Kiwi.InputBitPort("din")] static bool din;

static public void arraypart()
{
int odd = 0, even = 0;  // These are V_0 and V_1 in the ast.cil file.
int[] arr = new int [] {0, 1, 222221, 5, 7, 8, 1121, 2021, 2048};       // arr=V_2

arr[2] = 2;
// V_3 is the current element of the array
// V_4 is a copy of V_2
int pr = 0;
foreach (int i in arr) // i=V_6
{
if (i%2 == 0)
even++;
else
odd++;
Kiwi.Pause();
Console.Write("{1} i={0}: ", i, pr++);
Console.WriteLine("so far {0} Odd Numbers, and {1} Even Numbers.", odd, even);
}
Console.WriteLine("Found {0} Odd Numbers, and {1} Even Numbers.", odd, even) ;
Kiwi.Pause();
}

public static void Main()
{
int j = 0;
arraypart();

if (false) while(true)
{
j = j + 1;
if (j >= limit) j = 0;
dout = din & (j % 2 > 0);
Console.WriteLine(" J={0}.", j);
Kiwi.Pause();
}
}
}
```

Hardware Generated (with structural hazards still present)

```module DUT(reset,  clk,  din,  dout);
input reset;
input clk;
input din;
output dout;
reg signed [31:0] DRSX32SS_AX_CC_SOL_QC_SOL[8:0];
integer mpc10;
integer Ttar0_3_V_6;
integer Ttar0_3_V_4;
integer Ttar0_3_V_3;
integer Ttar0_3_V_1;
integer Ttar0_3_V_0;
always   @(posedge clk )  begin
//Start HPR test4.exe
if (reset)  begin
Ttar0_3_V_0 <= 32'd0;
Ttar0_3_V_3 <= 32'd0;
Ttar0_3_V_6 <= 32'd0;
Ttar0_3_V_4 <= 32'd0;
Ttar0_3_V_1 <= 32'd0;
mpc10 <= 32'd0;

end
else  begin
case (mpc10)
2/*2:mpc10XS:":pcIS44:AG"*/:  begin
if ((Ttar0_3_V_6<8)) if (!(!(DRSX32SS_AX_CC_SOL_QC_SOL[1+Ttar0_3_V_6]%2)))  begin
mpc10 <= 4/*4:mpc10XS:":pcIS63:AG"*/;
Ttar0_3_V_0 <= 1+Ttar0_3_V_0;
Ttar0_3_V_4 <= DRSX32SS_AX_CC_SOL_QC_SOL[1+Ttar0_3_V_6];
end
else  begin
Ttar0_3_V_1 <= 1+Ttar0_3_V_1;
Ttar0_3_V_4 <= DRSX32SS_AX_CC_SOL_QC_SOL[1+Ttar0_3_V_6];
end
else mpc10 <= 8/*8:mpc10XS:":pcIS56:AG"*/;

Ttar0_3_V_6 <= 1+Ttar0_3_V_6;
Ttar0_3_V_3 <= 1+Ttar0_3_V_3;
\$write("%d i=%d: ", Ttar0_3_V_3, Ttar0_3_V_4);
\$display("so far %d Odd Numbers, and %d Even Numbers.", Ttar0_3_V_0, Ttar0_3_V_1);
if ((Ttar0_3_V_6>=8))
\$display("Found %d Odd Numbers, and %d Even Numbers.", Ttar0_3_V_0, Ttar0_3_V_1);
end

4/*4:mpc10XS:":pcIS63:AG"*/:  begin
if ((Ttar0_3_V_6<8)) if (!(!(DRSX32SS_AX_CC_SOL_QC_SOL[1+Ttar0_3_V_6]%2)))  begin
Ttar0_3_V_0 <= 1+Ttar0_3_V_0;
end
else  begin
mpc10 <= 2/*2:mpc10XS:":pcIS44:AG"*/;
Ttar0_3_V_1 <= 1+Ttar0_3_V_1;
end
else mpc10 <= 8/*8:mpc10XS:":pcIS56:AG"*/;
Ttar0_3_V_4 <= DRSX32SS_AX_CC_SOL_QC_SOL[1+Ttar0_3_V_6];
Ttar0_3_V_6 <= 1+Ttar0_3_V_6;
Ttar0_3_V_3 <= 1+Ttar0_3_V_3;
\$write("%d i=%d: ", Ttar0_3_V_3, Ttar0_3_V_4);
\$display("so far %d Odd Numbers, and %d Even Numbers.", Ttar0_3_V_0, Ttar0_3_V_1);
if ((Ttar0_3_V_6>8))
\$display("Found %d Odd Numbers, and %d Even Numbers.", Ttar0_3_V_0, Ttar0_3_V_1);

end

8/*8:mpc10XS:":pcIS56:AG"*/: \$finish(0);
endcase
if ((0==mpc10))  begin
mpc10 <= 2/*2:mpc10XS:":pcIS44:AG"*/;
Ttar0_3_V_1 <= 1;
Ttar0_3_V_4 <= 0;
Ttar0_3_V_6 <= 0;
Ttar0_3_V_3 <= 0;
Ttar0_3_V_0 <= 0;
DRSX32SS_AX_CC_SOL_QC_SOL[2] <= 2;
DRSX32SS_AX_CC_SOL_QC_SOL[7] <= 2021;
DRSX32SS_AX_CC_SOL_QC_SOL[5] <= 8;
DRSX32SS_AX_CC_SOL_QC_SOL[3] <= 5;
DRSX32SS_AX_CC_SOL_QC_SOL[1] <= 1;
DRSX32SS_AX_CC_SOL_QC_SOL[0] <= 0;
DRSX32SS_AX_CC_SOL_QC_SOL[4] <= 7;
DRSX32SS_AX_CC_SOL_QC_SOL[6] <= 1121;
DRSX32SS_AX_CC_SOL_QC_SOL[8] <= 2048;
end
if ((mpc10==8/*8:mpc10XS:":pcIS56:AG"*/))  mpc10 <= 1/*1:mpc10XS:":pcIS-10:AG"*/;
end
//End HPR test4.exe
end
// 9 array locations of width 32
// 192 bits in scalar variables
// Total state bits in module = 480 bits.
endmodule
// eof (HPR/LS Verilog)

```

Simulation Output without Restructuring

The following output is generated either by running the test4.exe on mono or Windows or by simulating the DUT.v component using an RTL simulator (e.g. Modelsim):
```0 i=0: so far 0 Odd Numbers, and 1 Even Numbers.
1 i=1: so far 1 Odd Numbers, and 1 Even Numbers.
2 i=2: so far 1 Odd Numbers, and 2 Even Numbers.
3 i=5: so far 2 Odd Numbers, and 2 Even Numbers.
4 i=7: so far 3 Odd Numbers, and 2 Even Numbers.
5 i=8: so far 3 Odd Numbers, and 3 Even Numbers.
6 i=1121: so far 4 Odd Numbers, and 3 Even Numbers.
7 i=2021: so far 5 Odd Numbers, and 3 Even Numbers.
8 i=2048: so far 5 Odd Numbers, and 4 Even Numbers.
Found 5 Odd Numbers, and 4 Even Numbers.
```

```module SIMSYS();
reg clk, reset;
initial begin reset = 1; clk = 0; # 400 reset = 0; end
always #100 clk = !clk;
DUT dut(.clk(clk), .reset(reset));
initial # 1000000 \$finish();
endmodule
// eof
```

Restructured to use an SRAM

After restructuring, a specific, single-ported RAM component is instantiated in the RTL with busses to access it. This can be included in the main always block (as shown below) or be a separate RTL module with a structural instantiation:

```      //Start HPR HPR_RAM_1_32
always   @(posedge clk )  begin
end
//End HPR HPR_RAM_1_32
```

The generated RTL now looks like this DUT-R.v.

These busses are driven by the main code. The address bus is registered to suite pipelined RAM blocks typically used in FPGA and ASIC. The address needs to be one cycle earlier than the data (but does not appear as such in the timing diagram since AD0 has a blocking assign at the start of the always block).

As can be seen, additional clock cycles are used to sequence the operations on the memory port. Such splitting of a paus block into microstates would be a compile-time error in 'HardPauseMode' where the compiler must strictly obey the Kiwi.Pause calls embedded in the C# code.

Modified timing diagram: additional cycles of additional program counter (mpc10zz) sequence the writes:

31st May 2011.             UP.