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).
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; dObject 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 endmoduleAlternate 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 # eofSimulation 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 // eofTiming Waveforms
LARGER.
Updated April 2016 UP.