diff --git a/Artix-7-HDMI-processing.xpr b/Artix-7-HDMI-processing.xpr
index 6c0ad59..492b92a 100644
--- a/Artix-7-HDMI-processing.xpr
+++ b/Artix-7-HDMI-processing.xpr
@@ -42,7 +42,7 @@
-
+
@@ -245,6 +245,14 @@
+
+
+
+
+
+
+
+
@@ -266,8 +274,16 @@
+
+
+
+
+
+
+
+
@@ -373,9 +389,14 @@
+
+
+
+
+
-
+
@@ -390,6 +411,7 @@
+
diff --git a/spi_regfile_tb_behav.wcfg b/spi_regfile_tb_behav.wcfg
new file mode 100644
index 0000000..4735b15
--- /dev/null
+++ b/spi_regfile_tb_behav.wcfg
@@ -0,0 +1,181 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ testcase[31:0]
+ testcase[31:0]
+
+
+ clk
+ clk
+
+
+ rst
+ rst
+
+
+ sck
+ sck
+
+
+ sdi
+ sdi
+
+
+ sdo
+ sdo
+
+
+ ncs
+ ncs
+
+
+ spi_data_in[15:0]
+ spi_data_in[15:0]
+
+
+ spi_data_out[15:0]
+ spi_data_out[15:0]
+
+
+ spi_status_word[15:0]
+ spi_status_word[15:0]
+
+
+ spi_cmd_word[15:0]
+ spi_cmd_word[15:0]
+
+
+ spi_cmd_begin
+ spi_cmd_begin
+
+
+ spi_cmd_active
+ spi_cmd_active
+
+
+ spi_cmd_step
+ spi_cmd_step
+
+
+ spi_cmd_idx[19:0]
+ spi_cmd_idx[19:0]
+
+
+ i[31:0]
+ i[31:0]
+
+
+ j[31:0]
+ j[31:0]
+
+
+ k[31:0]
+ k[31:0]
+
+
+ sim_rxdata[1:4][15:0]
+ sim_rxdata[1:4][15:0]
+
+
+ sim_txdata[1:4][15:0]
+ sim_txdata[1:4][15:0]
+
+
+ sim_txbuf[15:0]
+ sim_txbuf[15:0]
+
+
+ period[31:0]
+ period[31:0]
+
+
+ WORDSIZE[31:0]
+ WORDSIZE[31:0]
+
+
+ data_out[15:0]
+ data_out[15:0]
+ #FFFF00
+ true
+
+
+ data_out_valid
+ data_out_valid
+ #FFFF00
+ true
+
+
+ data_in[15:0]
+ data_in[15:0]
+ #FFFF00
+ true
+
+
+ data_in_valid
+ data_in_valid
+ #FFFF00
+ true
+
+
+ sck_rising
+ sck_rising
+ #FFFF00
+ true
+
+
+ sck_falling
+ sck_falling
+ #FFFF00
+ true
+
+
+ tx_buf[15:0]
+ tx_buf[15:0]
+ #FFFF00
+ true
+
+
+ tx_buf_next[15:0]
+ tx_buf_next[15:0]
+ #FFFF00
+ true
+
+
+ is_spi_cmd_word
+ is_spi_cmd_word
+ #FAAFBE
+ true
+
+
+ spi_core_cs_rising
+ spi_core_cs_rising
+ #FAAFBE
+ true
+
+
+ spi_core_cs_falling
+ spi_core_cs_falling
+ #FAAFBE
+ true
+
+
diff --git a/src/spi_core.v b/src/spi_core.v
index bf828ab..41b66e0 100644
--- a/src/spi_core.v
+++ b/src/spi_core.v
@@ -1,3 +1,4 @@
+`timescale 1ns / 1ps
module spi_core(
input clk, rst,
diff --git a/src/spi_regfile.v b/src/spi_regfile.v
new file mode 100644
index 0000000..f211dac
--- /dev/null
+++ b/src/spi_regfile.v
@@ -0,0 +1,85 @@
+`timescale 1ns / 1ps
+
+module spi_regfile(
+ input clk, rst,
+
+ input sck, sdi, ncs,
+ output sdo,
+
+ input [15:0] spi_data_in,
+ output reg [15:0] spi_data_out,
+
+ input [15:0] spi_status_word,
+ output reg [15:0] spi_cmd_word,
+ output reg spi_cmd_begin,
+ output reg spi_cmd_active,
+ output reg spi_cmd_step,
+ output reg [19:0] spi_cmd_idx
+);
+
+wire spi_core_cs_rising, spi_core_cs_falling;
+reg [15:0] spi_core_data_in;
+reg spi_core_data_in_valid;
+wire [15:0] spi_core_data_out;
+wire spi_core_data_out_valid;
+
+reg is_spi_cmd_word;
+
+always @(posedge clk) begin
+ spi_core_data_in_valid <= 0;
+ spi_cmd_begin <= 0;
+ spi_cmd_step <= 0;
+ spi_core_data_in <= spi_status_word;
+
+ if (rst) begin
+ is_spi_cmd_word <= 1;
+ spi_cmd_active <= 0;
+ spi_cmd_idx <= 0;
+
+ end else begin
+
+ if (spi_core_cs_rising) begin
+ is_spi_cmd_word <= 1;
+ spi_cmd_active <= 0;
+ end
+
+ if (ncs) begin
+ /* constantly refresh status word */
+ spi_core_data_in_valid <= 1;
+ end
+
+ if (spi_core_data_out_valid) begin
+ spi_core_data_in <= spi_data_in;
+ spi_core_data_in_valid <= 1;
+
+ if (is_spi_cmd_word) begin
+ spi_cmd_word <= spi_core_data_out;
+ spi_cmd_idx <= 0;
+ spi_cmd_active <= 1;
+ spi_cmd_begin <= 1;
+ is_spi_cmd_word <= 0;
+
+ end else begin
+ spi_cmd_idx <= spi_cmd_idx + 1;
+ spi_cmd_step <= 1;
+ spi_data_out <= spi_core_data_out;
+ end
+ end
+ end
+end
+
+spi_core #(.WORDSIZE(16)) spi_core_dut (
+ .clk(clk), .rst(rst),
+
+ .sck(sck), .sdi(sdi), .sdo(sdo), .ncs(ncs),
+
+ .cs_rising(spi_core_cs_rising),
+ .cs_falling(spi_core_cs_falling),
+
+ .data_out(spi_core_data_out),
+ .data_out_valid(spi_core_data_out_valid),
+ .data_in(spi_core_data_in),
+ .data_in_valid(spi_core_data_in_valid)
+);
+
+endmodule
diff --git a/test_bench/spi_core_tb.v b/test_bench/spi_core_tb.v
index fff7fa1..4a2e6a2 100644
--- a/test_bench/spi_core_tb.v
+++ b/test_bench/spi_core_tb.v
@@ -1,3 +1,4 @@
+`timescale 1ns / 1ps
module spi_core_tb();
diff --git a/test_bench/spi_regfile_tb.v b/test_bench/spi_regfile_tb.v
new file mode 100644
index 0000000..9831475
--- /dev/null
+++ b/test_bench/spi_regfile_tb.v
@@ -0,0 +1,134 @@
+`timescale 1ns / 1ps
+
+module spi_regfile_tb();
+
+localparam period = 10;
+parameter WORDSIZE = 16;
+reg clk, rst;
+
+reg sck, sdi, ncs;
+wire sdo;
+
+reg [15:0] spi_data_in;
+wire [15:0] spi_data_out;
+wire [15:0] spi_status_word = 16'h3141;
+wire [15:0] spi_cmd_word;
+wire spi_cmd_begin, spi_cmd_active, spi_cmd_step;
+wire [19:0] spi_cmd_idx;
+
+initial begin
+ clk = 0;
+ /* rst set below */
+ sck = 0;
+ sdi = 0;
+ ncs = 1;
+ forever #period clk = ~clk;
+end
+
+integer i;
+integer j;
+integer k;
+integer testcase;
+reg [WORDSIZE-1:0] sim_rxdata [1:4];
+reg [WORDSIZE-1:0] sim_txdata [1:4];
+reg [WORDSIZE-1:0] sim_txbuf;
+initial begin
+ sim_rxdata[1] = 16'h523a;
+ sim_rxdata[2] = 16'hbeef;
+ sim_rxdata[3] = 16'h7721;
+ sim_rxdata[4] = 16'h0108;
+
+ sim_txdata[1] = 16'h1234;
+ sim_txdata[2] = 16'h5678;
+ sim_txdata[3] = 16'h9abc;
+ sim_txdata[4] = 16'hdef9;
+
+ for (j=1; j<=4; j=j+1) begin
+ $display("TC-%d: rx/tx %d word", j, j);
+ testcase = j;
+
+ rst = 1;
+ repeat(2) @(posedge clk);
+ rst = 0;
+ @(posedge clk);
+
+ spi_data_in = sim_txdata[1];
+ @(posedge clk);
+
+ ncs = 0;
+ @(posedge clk);
+ @(posedge clk);
+ if (spi_cmd_begin) $finish;
+ if (spi_cmd_active) $finish;
+ if (spi_cmd_step) $finish;
+
+ for (k=0; k 0 && spi_cmd_begin) $finish;
+ if (k == 0 && spi_cmd_step) $finish;
+ if (k > 0 && !spi_cmd_step) $finish;
+ if (spi_cmd_word != sim_rxdata[1]) $finish;
+ if (k > 0 && spi_data_out != sim_rxdata[k+1]) $finish;
+ if (k == 0 && sim_txbuf != 16'h3141) $finish;
+ if (k > 0 && sim_txbuf != sim_txdata[k]) $finish;
+ end
+
+ sck = 0;
+ @(posedge clk);
+ ncs = 1;
+ @(posedge clk);
+ @(posedge clk);
+
+ if (spi_cmd_active) $finish;
+ if (spi_cmd_step) $finish;
+ if (spi_cmd_begin) $finish;
+
+ repeat(10) @(posedge clk);
+ end
+
+ $finish;
+end
+
+spi_regfile spi_regfile_dut (
+ .clk(clk), .rst(rst),
+
+ .sck(sck), .sdi(sdi), .sdo(sdo), .ncs(ncs),
+
+ .spi_data_in(spi_data_in),
+ .spi_data_out(spi_data_out),
+
+ .spi_status_word(spi_status_word),
+ .spi_cmd_word(spi_cmd_word),
+ .spi_cmd_begin(spi_cmd_begin),
+ .spi_cmd_active(spi_cmd_active),
+ .spi_cmd_step(spi_cmd_step),
+ .spi_cmd_idx(spi_cmd_idx)
+);
+
+endmodule
\ No newline at end of file