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

The C# source code for this example is DOWNLOAD:

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)

The following RTL contains hazards on the memory writes DOWNLOAD.
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.

Testwrapper DOWNLOAD:

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
        if (DRSX32SS_AX_CC_SOL_QC_SOL_WEN0)  DRSX32SS_AX_CC_SOL_QC_SOL[DRSX32SS_AX_CC_SOL_QC_SOL_registered_AD0] <= DRSX32SS_AX_CC_SOL_QC_SOL_WRD0;
       DRSX32SS_AX_CC_SOL_QC_SOL_RDD0 = DRSX32SS_AX_CC_SOL_QC_SOL[DRSX32SS_AX_CC_SOL_QC_SOL_registered_AD0];
       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.