Orangepath/HPR Logic Synthesis Project: Hardware and Embedded Software Synthesis from Executable Specifications.
Compilation from .net CIL Bytecode (second example)

Kiwi Simple Demo: Simple Seven-Segment Driver for FPGA from CSharp

Scan-multiplexed LED display driver simple demo.

One display digit is illuminated at a time according to which segement strobe is active. The human eye integrates this and does not see any flicker provided the scanning is sufficiently fast (> 100 Hz).

Source File

The following CSharp file was compiled with mono mcs.

//
// Kiwi Scientific Acceleration - Simple 7-segment display driver - net level
// (C) 2008 D J Greaves, University of Cambridge Computer Laboratory.

// 


using System;
using System.Text;
using KiwiSystem;


public static class seven_segment
{
  const int n_digits = 4;
  
   
  [Kiwi.InputBitPort("clear")] static bool clear;
  [Kiwi.OutputWordPort("segments")] static uint segments;
  [Kiwi.OutputWordPort("strobes")] static uint strobes;

  // Digit data in an array
  static int [] digit_data = new int [n_digits];

  // Seven segment character set ROM
  // Digits 0-9 and a minus sign. Bit g is lsb, zero for on.
  static int [] cbg_seven_seg = new int [] { 0x01, 0x4f, 0x12, 0x06, 0x4c, 0x24, 0x60, 0x0f, 0x00, 0x0c, 0x7E };


  static int seven_seg_encode_data(int d)
  {
    return cbg_seven_seg[d];
  }


  static int digit_on_display = 0;


  static void scan()
  {
    digit_on_display = (digit_on_display + 1) % n_digits;
    strobes = 1u << digit_on_display;
    segments = (uint)(seven_seg_encode_data(digit_data[digit_on_display]));
    for (int delay=0;delay<4; delay++) Kiwi.Pause();
  }


  static public void reset_data()
  {
    for (int i=0; i < n_digits; i++)
      {
	digit_data[i] = 0;	  
      }
  }

  static void increment_bcd()
  {
    for (int d=0; d


Object File

The dotnet .exe file was converted to the following Verilog RTL file with KiwiC.

// Verilog output file generated at 29/04/2016 14:28:14
// Kiwi Scientific Acceleration (KiwiC .net/CIL/C# to Verilog/SystemC compiler): Version alpha 2.03c Interim: 25-Apr-2016 Unix 3.13.0.65
//  /home/djg11/d320/hprls/kiwipro/kiwic/distro/lib/kiwic.exe seven-segment.exe -vnl-roundtrip=disable -vnl-resets=synchronous -vnl=seven-segment.v -vnl-rootmodname=DUT


module DUT(input clear, output reg [31:0] segments, output reg [31:0] strobes, input clk, input reset);
  integer seven_segment_digit_on_display;
  integer sTMT4Main_V_0;
  integer Tsre2_0_V_0;
  integer Tssc3_5_V_0;
  integer Tsin4_0_V_0;
  integer Tsin4_0_V_1;
  reg signed [31:0] A_SINT_CC_SCALbx12_ARB0[10:0];
  reg signed [31:0] A_SINT_CC_SCALbx10_ARA0[3:0];
  reg [3:0] xpc10nz;
 always   @(posedge clk )  begin 
      //Start structure HPR seven-segment.exe
      if (reset)  begin 
               Tsre2_0_V_0 <= 32'd0;
               strobes <= 32'd0;
               segments <= 32'd0;
               Tsin4_0_V_1 <= 32'd0;
               Tsin4_0_V_0 <= 32'd0;
               Tssc3_5_V_0 <= 32'd0;
               seven_segment_digit_on_display <= 32'd0;
               sTMT4Main_V_0 <= 32'd0;
               xpc10nz <= 4'd0;
               end 
               else  begin 
              
              case (xpc10nz)
                  0/*0:US*/:  begin 
                       seven_segment_digit_on_display <= 32'd0;
                       sTMT4Main_V_0 <= 32'd0;
                       A_SINT_CC_SCALbx10_ARA0[2'd3] <= 32'd0;
                       A_SINT_CC_SCALbx10_ARA0[2'd2] <= 32'd0;
                       A_SINT_CC_SCALbx10_ARA0[1'd1] <= 32'd0;
                       A_SINT_CC_SCALbx10_ARA0[0] <= 32'd0;
                       xpc10nz <= 4'd9/*9:xpc10nz*/;
                       end 
                      
                  1'd1/*1:US*/:  begin 
                       Tssc3_5_V_0 <= 32'd1+Tssc3_5_V_0;
                       xpc10nz <= 3'd6/*6:xpc10nz*/;
                       end 
                      
                  2'd2/*2:US*/: if (!(!Tsin4_0_V_1))  begin 
                           A_SINT_CC_SCALbx10_ARA0[Tsin4_0_V_0] <= 32'hffffffff&Tsin4_0_V_1;
                           xpc10nz <= 3'd4/*4:xpc10nz*/;
                           end 
                           else  begin 
                           Tsin4_0_V_0 <= 32'd1+Tsin4_0_V_0;
                           A_SINT_CC_SCALbx10_ARA0[Tsin4_0_V_0] <= 32'hffffffff&Tsin4_0_V_1;
                           xpc10nz <= 3'd5/*5:xpc10nz*/;
                           end 
                          
                  3'd4/*4:US*/:  begin 
                       sTMT4Main_V_0 <= 32'd0;
                       xpc10nz <= 2'd3/*3:xpc10nz*/;
                       end 
                      
                  3'd5/*5:US*/:  begin 
                      if ((Tsin4_0_V_0<3'd4))  xpc10nz <= 2'd2/*2:xpc10nz*/;
                           else  xpc10nz <= 3'd4/*4:xpc10nz*/;
                      if ((Tsin4_0_V_0<3'd4) && (4'd10/*10:MS*/==(32'hffffffff&Tsin4_0_V_0+A_SINT_CC_SCALbx10_ARA0[Tsin4_0_V_0])))  Tsin4_0_V_1
                           <= 32'd0;

                          if ((Tsin4_0_V_0<3'd4) && (4'd10/*10:MS*/!=(32'hffffffff&Tsin4_0_V_0+A_SINT_CC_SCALbx10_ARA0[Tsin4_0_V_0]))) 
                       Tsin4_0_V_1 <= Tsin4_0_V_0+A_SINT_CC_SCALbx10_ARA0[Tsin4_0_V_0];
                           end 
                      
                  3'd6/*6:US*/:  begin 
                      if ((Tssc3_5_V_0>=3'd4) && (sTMT4Main_V_0==4'd10/*10:US*/))  begin 
                               Tsin4_0_V_0 <= 32'd0;
                               xpc10nz <= 3'd5/*5:xpc10nz*/;
                               end 
                              if ((Tssc3_5_V_0>=3'd4) && (sTMT4Main_V_0!=4'd10/*10:US*/))  xpc10nz <= 2'd3/*3:xpc10nz*/;
                          if ((Tssc3_5_V_0<3'd4))  xpc10nz <= 1'd1/*1:xpc10nz*/;
                           end 
                      
                  3'd7/*7:US*/:  begin 
                       strobes <= (32'd1<<(5'd31&32'hffffffff&((1'd1+seven_segment_digit_on_display)%3'd4)));
                       segments <= A_SINT_CC_SCALbx12_ARB0[A_SINT_CC_SCALbx10_ARA0[32'hffffffff&((1'd1+seven_segment_digit_on_display
                      )%3'd4)]];

                       Tssc3_5_V_0 <= 32'd0;
                       seven_segment_digit_on_display <= ((1'd1+seven_segment_digit_on_display)%3'd4);
                       sTMT4Main_V_0 <= 32'd1+sTMT4Main_V_0;
                       xpc10nz <= 3'd6/*6:xpc10nz*/;
                       end 
                      
                  4'd8/*8:US*/: if ((Tsre2_0_V_0<3'd4))  begin 
                           Tsre2_0_V_0 <= 32'd1+Tsre2_0_V_0;
                           A_SINT_CC_SCALbx10_ARA0[Tsre2_0_V_0] <= 32'd0;
                           xpc10nz <= 4'd8/*8:xpc10nz*/;
                           end 
                           else  xpc10nz <= 3'd7/*7:xpc10nz*/;

                  4'd9/*9:US*/: if (clear)  begin 
                           Tsre2_0_V_0 <= 32'd0;
                           xpc10nz <= 4'd8/*8:xpc10nz*/;
                           end 
                           else  xpc10nz <= 3'd7/*7:xpc10nz*/;
              endcase
              if ((xpc10nz==2'd3/*3:US*/))  xpc10nz <= 4'd9/*9:xpc10nz*/;
                   end 
              //End structure HPR seven-segment.exe


       end 

 initial        begin 
      //ROM data table: 11 words of 32 bits.
       A_SINT_CC_SCALbx12_ARB0[0] = 32'h1;
       A_SINT_CC_SCALbx12_ARB0[1] = 32'h4f;
       A_SINT_CC_SCALbx12_ARB0[2] = 32'h12;
       A_SINT_CC_SCALbx12_ARB0[3] = 32'h6;
       A_SINT_CC_SCALbx12_ARB0[4] = 32'h4c;
       A_SINT_CC_SCALbx12_ARB0[5] = 32'h24;
       A_SINT_CC_SCALbx12_ARB0[6] = 32'h60;
       A_SINT_CC_SCALbx12_ARB0[7] = 32'hf;
       A_SINT_CC_SCALbx12_ARB0[8] = 32'h0;
       A_SINT_CC_SCALbx12_ARB0[9] = 32'hc;
       A_SINT_CC_SCALbx12_ARB0[10] = 32'h7e;
       end 
      
// 1 vectors of width 4
// 15 array locations of width 32
// 192 bits in scalar variables
// Total state bits in module = 676 bits.
// Total number of leaf cells = 0
endmodule

Alternate output code when ROMs were disabled: withoutrom.v.

Alternate output code with pipelined ROMs: withoutrom.v.

Makefile

#
# Kiwi Scientific Acceleration - Simple 7-segment display driver - net level
# (C) 2008 D J Greaves, University of Cambridge Computer Laboratory.

# 
# Scan-multiplexed LED display driver simple demo.
# 
# One display digit is illuminated at a time according to which segement strobe is active.
# The human eye integrates this and does not see any flicker provided the scanning is sufficiently fast (> 100 Hz).


SRC=seven-segment

MCS    ?=mcs
KLIB1   ?=${HPRLS}/kiwipro/kiwic/distro/support/Kiwi.dll
KIWIC   ?=${HPRLS}/kiwipro/kiwic/distro/bin/kiwic


simulate: $(SRC).v vsys.v
	iverilog  $(SRC).v vsys.v 
	./a.out
	cp vcd.vcd ~/Dropbox

$(SRC).v: $(SRC).exe
	$(KIWIC) $(SRC).exe -vnl-roundtrip=disable -vnl-resets=synchronous -restructure2=disable -vnl=seven-segment.v -vnl-rootmodname=DUT

# -res2-no-dram-ports=0

$(SRC).exe: $(SRC).cs
	$(MCS) $(SRC).cs -r $(KLIB1)

zip:
	zip kiwi-sevenseg-demo.zip Makefile $(SRC).v $(SRC).cs vsys.v kiwi-seven-segment-drive-waveforms.png



# eof

Simulation Test Bench

//
// Kiwi Scientific Acceleration  
// University of Cambridge, Computer Laboratory
//
// vsys.v - A test wrapper for simulating very simple tests with clock and reset.
// 
//
//
`timescale 1ns/10ps

module SIMSYS();

   reg clk, reset;
   initial begin reset = 1; clk = 1; # 43 reset = 0; end
   always #5 clk = !clk;
   initial begin # (100 * 1000) $display("Finish HDL simulation on timeout %t.", $time); $finish(); end

   initial begin $dumpfile("vcd.vcd"); $dumpvars(); end

   wire clear = 0;   
   wire [7:0] segments;
   wire [3:0] strobes;

   DUT the_dut(.clk(clk), .reset(reset), .clear(clear), .strobes(strobes), .segments(segments));

     always @(posedge clk) begin
//	$display("pc, thread0 = %d", the_dut.xpc10nz);
	end

endmodule
// eof

Timing Waveforms

LARGER.

Updated April 2016               UP.