[RTL] PRGA fullsim
diff --git a/verilog/dv/prga/bitgen.out b/verilog/dv/prga/bitgen.out
new file mode 100644
index 0000000..791749c
--- /dev/null
+++ b/verilog/dv/prga/bitgen.out
@@ -0,0 +1,422 @@
+0000000c80000002
+02c1e90002000000
+1480000080000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000002000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000080100000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000004000000002
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+000000000000a400
+0200000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000001
+0000080000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000200200
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000080000
+0000000300000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0100004000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000520001000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000008040000000
+0400000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000804
+8000100000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000804800100000
+4000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000a01208
+0400c00c00000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000820
+8000402010008000
+0000000000000000
+0000000000000000
+0000008000005100
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000200000010000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000020000
+00000000014d8923
+09e92c4012f3d36d
+cd6d7e053d80725a
+822580655805c5a2
+a0580563ff805806
+5241341800002000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000804000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000002000000
+0010061a60004124
+9011c20022000080
+0000000000000000
+1100000000000000
+0000248040000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000030000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000400
+0000050040000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+00100020000a049a
+4000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+000000000034180c
+0440523100000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0c82002008004100
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000100804000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0020000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0060000000060051
+0504848200600427
+02080030401be800
+0800000000200402
+6080000000200000
+0000000000001642
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000020200000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000080180002002
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000010400
+00032a4480000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0120911840240682
+0dbc95d6ec619104
+115d3ab48da272d4
+d601dcf5004f7740
+e000779d4174140e
+008ee02009a50c91
+2810000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+1001800000410600
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0001800000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000c00450450021
+301b483402034946
+d9904f40238db900
+000e2d5540104000
+001c400180182000
+0000400000000300
+0c00005000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0400000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000002
+0000004400000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0004104000004076
+0085e49e8de06ea0
+5056fcd6abbfe569
+30bf4f07003fbf4f
+8bff4875e4c7ee00
+b51407f0f0614882
+6cc1000c04cd36c7
+21d738821b54a951
+c6ec009abbeaba71
+1007031370c0cb0d
+0c7ff0078888bfcf
+e64c49104cfe2402
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+000000004d841309
+0024400000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+1040000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0044104c00430180
+02202000020c018e
+00c038da8829c0c6
+ba06936db6641c00
+601b0c0004e00800
+0200060080000001
+0000200004000008
+0000100000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000004442
+00dd018cc0880049
+32132c0000000000
+3818038202380180
+0000000000000000
+00000000318c4000
+082424c4ad763c66
+09415a29d964ada7
+6a6fb5140b0404b0
+e027ff30bdddc731
+7574004b0073a75a
+1501119000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+6ea64f2222200000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000eec82c008800
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000000000000
+0000000044000000
+0182d4c0a508b0c0
+10b88000a1800120
+0001000100010001
+0001000101010001
diff --git a/verilog/dv/prga/prga_bitstream_loader.v b/verilog/dv/prga/prga_bitstream_loader.v
new file mode 100644
index 0000000..771af8d
--- /dev/null
+++ b/verilog/dv/prga/prga_bitstream_loader.v
@@ -0,0 +1,154 @@
+module prga_bitstream_loader (
+    input wire tb_clk
+    , input wire tb_rst
+    , input wire [31:0] tb_cycle_cnt
+    , output reg tb_prog_done
+
+    , output wire prog_clk
+    , output wire prog_rst
+    , output wire prog_done
+    , output reg prog_we
+    , output reg prog_din
+    , input wire prog_dout
+    , input wire prog_we_o
+    );
+
+    // Bitstream stuff
+    localparam  BS_NUM_QWORDS       = 422,
+                BS_WORD_SIZE        = 1;
+
+    // Programming protocol
+    localparam  INIT            = 3'd0,
+                RESET           = 3'd1,
+                PROG_WAIT       = 3'd2,
+                PROGRAMMING     = 3'd3,
+                PROG_STABLIZING = 3'd4,
+                PROG_DONE       = 3'd5;
+
+    reg [2:0]                   state;
+    reg [31:0]                  wait_cnt;
+    reg [63:0]                  bs_data [0:BS_NUM_QWORDS];
+
+    reg                         prog_we_prev, prog_we_o_prev;
+    reg [63:0]                  prog_progress;
+    reg [31:0]                  prog_fragments;
+
+    // Load bitstream
+    initial begin
+        tb_prog_done = 1'b0;
+
+        state = INIT;
+        wait_cnt = 0;
+        prog_we = 1'b0;
+        prog_we_prev = 1'b0;
+        prog_we_o_prev = 1'b0;
+        prog_din = {BS_WORD_SIZE {1'b0} };
+        prog_progress = 64'b0;
+        prog_fragments = 32'b0;
+
+        $display("[INFO] Bitstream: %s", "bitgen.out");
+
+        $readmemh("bitgen.out", bs_data);
+        bs_data[BS_NUM_QWORDS] = 64'b0;
+    end
+
+    // Programming FSM
+    always @(posedge tb_clk) begin
+        if (tb_rst) begin
+            state <= RESET;
+            prog_progress <= 64'b0;
+            wait_cnt <= 0;
+            prog_we <= 1'b0;
+        end else begin
+            case (state)
+                RESET: begin
+                    state <= PROG_WAIT;
+                end
+                PROG_WAIT: begin
+                    if (wait_cnt == 100) begin
+                        state <= PROGRAMMING;
+                    end else begin
+                        wait_cnt <= wait_cnt + 1;
+                    end
+                end
+                PROGRAMMING: begin
+                    if (prog_we) begin
+                        if (prog_progress + BS_WORD_SIZE >= BS_NUM_QWORDS * 64) begin
+                            $display("[INFO] [Cycle %04d] Bitstream writing completed", tb_cycle_cnt);
+                            prog_we <= 1'b0;
+                            state <= PROG_STABLIZING;
+                        end else begin
+                            prog_we <= {$random} % 100 > 2 ? 1'b1 : 1'b0;   // 2% chance to turn off prog_we
+                            prog_progress <= prog_progress + BS_WORD_SIZE;
+                        end
+                    end else begin
+                        prog_we <= {$random} % 100 > 2 ? 1'b1 : 1'b0;   // 2% chance to turn off prog_we
+                    end
+                end
+                PROG_STABLIZING: begin
+                    if (prog_fragments == 0) begin
+                        $display("[INFO] [Cycle %04d] Bitstream loading completed", tb_cycle_cnt);
+                        state <= PROG_DONE;
+                    end
+                end
+            endcase
+        end
+    end
+
+    // track "we" toggling
+    always @(posedge tb_clk) begin
+        if (tb_rst) begin
+            prog_we_prev <= 1'b0;
+            prog_we_o_prev <= 1'b0;
+            prog_fragments <= 32'b0;
+        end else begin
+            prog_we_prev <= prog_we;
+            prog_we_o_prev <= prog_we_o;
+
+            if ((prog_we_prev && ~prog_we) && ~(prog_we_o_prev && ~prog_we_o)) begin
+                prog_fragments <= prog_fragments + 1;
+            end else if (~(prog_we_prev && ~prog_we) && (prog_we_o_prev && ~prog_we_o)) begin
+                prog_fragments <= prog_fragments - 1;
+            end
+        end
+    end
+
+    // Programming data
+    always @* begin
+        prog_din = {bs_data[prog_progress / 64], bs_data[prog_progress / 64 + 1]} >> (128 - BS_WORD_SIZE - prog_progress % 64);
+    end
+
+    // Progress tracking
+    reg [7:0]   prog_percentage;
+
+    always @(posedge tb_clk) begin
+        if (tb_rst) begin
+            prog_percentage <= 8'b0;
+        end else begin
+            if (prog_progress * 100 / BS_NUM_QWORDS / 64 > prog_percentage) begin
+                prog_percentage <= prog_percentage + 1;
+                $display("[INFO] Programming progress: %02d%%", prog_percentage + 1);
+            end
+        end
+    end
+
+    // tb prog_done
+    reg [31:0]  prog_done_cnt;
+
+    always @(posedge tb_clk) begin
+        if (tb_rst) begin
+            prog_done_cnt <= 100;
+            tb_prog_done <= 1'b0;
+        end else if (state == PROG_DONE && prog_done_cnt > 0) begin
+            prog_done_cnt <= prog_done_cnt - 1;
+
+            if (prog_done_cnt == 1)
+                tb_prog_done <= 1'b1;
+        end
+    end
+
+    assign prog_clk = tb_clk;
+    assign prog_rst = tb_rst;
+    assign prog_done = state == PROG_DONE;
+
+endmodule
diff --git a/verilog/dv/prga/prga_tb.v b/verilog/dv/prga/prga_tb.v
index 9f7e95d..735ee1c 100644
--- a/verilog/dv/prga/prga_tb.v
+++ b/verilog/dv/prga/prga_tb.v
@@ -143,7 +143,6 @@
     assign f_tb_rst = CSB || !gpio;
 
     wire w_tb_pass, w_tb_fail, w_tb_prog_done;
-    assign w_tb_prog_done = 1'b1;
 
     // Logging
     wire [31:0] f_tb_verbosity;
@@ -224,13 +223,61 @@
         );
 
     // -- Bitstream Loading --------------------------------------------------
+    wire prog_clk, prog_rst, prog_done, prog_we, prog_din, prog_dout, prog_we_o;
+
+    prga_bitstream_loader i_loader (
+        .tb_clk(clock)
+        ,.tb_rst(f_tb_rst)
+        ,.tb_cycle_cnt(f_tb_cycle_cnt)
+        ,.tb_prog_done(w_tb_prog_done)
+        ,.prog_clk(prog_clk)
+        ,.prog_rst(prog_rst)
+        ,.prog_done(prog_done)
+        ,.prog_we(prog_we)
+        ,.prog_din(prog_din)
+        ,.prog_dout(prog_dout)
+        ,.prog_we_o(prog_we_o)
+        );
+
+    // -- Implemented Circuit ------------------------------------------------
+    // Signals
+    wire w_impl_ready;
+    wire w_impl_done_tick;
+    wire [6:0] w_impl_bin;
 
     // -----------------------------------------------------------------------
     // -- Wiring -------------------------------------------------------------
     // -----------------------------------------------------------------------
-    assign w_test_ready = w_behav_ready;
-    assign w_test_done_tick = w_behav_done_tick;
-    assign w_test_bin = w_behav_bin;
+    assign w_test_ready = w_impl_ready;
+    assign w_test_done_tick = w_impl_done_tick;
+    assign w_test_bin = w_impl_bin;
+
+    assign mprj_io[37] = prog_clk;
+    assign mprj_io[36] = w_test_clk;
+    assign mprj_io[35] = prog_din;
+    assign mprj_io[34] = prog_done;
+    assign mprj_io[33] = prog_rst;
+    assign mprj_io[32] = prog_we;
+    assign mprj_io[31] = 1'b0;
+    assign mprj_io[30] = w_test_reset;
+    assign mprj_io[29] = w_test_start;
+    assign mprj_io[28] = w_test_bcd1[0];
+    assign mprj_io[27] = w_test_bcd1[1];
+    assign mprj_io[26] = w_test_bcd1[2];
+    assign mprj_io[25] = w_test_bcd1[3];
+    assign mprj_io[24] = w_test_bcd0[0];
+    assign mprj_io[23] = w_test_bcd0[1];
+    assign mprj_io[22] = w_test_bcd0[2];
+    assign mprj_io[21] = w_test_bcd0[3];
+    assign w_impl_ready = mprj_io[20];
+    assign w_impl_done_tick = mprj_io[19];
+    assign w_impl_bin[0] = mprj_io[18];
+    assign w_impl_bin[1] = mprj_io[17];
+    assign w_impl_bin[2] = mprj_io[16];
+    assign w_impl_bin[3] = mprj_io[14];
+    assign w_impl_bin[4] = mprj_io[13];
+    assign w_impl_bin[5] = mprj_io[12];
+    assign w_impl_bin[6] = mprj_io[11];
 
 endmodule
 `default_nettype wire