aboutsummaryrefslogtreecommitdiff
path: root/src/arc4.sv
diff options
context:
space:
mode:
Diffstat (limited to 'src/arc4.sv')
-rw-r--r--src/arc4.sv154
1 files changed, 154 insertions, 0 deletions
diff --git a/src/arc4.sv b/src/arc4.sv
new file mode 100644
index 0000000..453c1f2
--- /dev/null
+++ b/src/arc4.sv
@@ -0,0 +1,154 @@
+module arc4 (
+ input logic clk,
+ input logic rst_n,
+ input logic en,
+ output logic rdy,
+ input logic [23:0] key,
+
+ output logic [7:0] ct_addr,
+ input logic [7:0] ct_rddata,
+
+ output logic [7:0] pt_addr,
+ input logic [7:0] pt_rddata,
+ output logic [7:0] pt_wrdata,
+ output logic pt_wren
+);
+
+ logic s_wren;
+ logic [7:0] s_addr;
+ logic [7:0] s_wrdata, s_rddata;
+
+ logic i_en, i_rdy, i_wren;
+ logic [7:0] i_addr;
+ logic [7:0] i_wrdata;
+
+ logic k_en, k_rdy, k_wren;
+ logic [7:0] k_addr;
+ logic [7:0] k_wrdata;
+
+ logic p_en, p_rdy, p_s_wren, p_pt_wren;
+ logic [7:0] p_s_addr, p_ct_addr, p_pt_addr;
+ logic [7:0] p_s_wrdata, p_pt_wrdata;
+
+ enum logic [2:0] {
+ IDLE,
+ INIT_BEGIN,
+ INIT,
+ KSA_BEGIN,
+ KSA,
+ PRGA_BEGIN,
+ PRGA,
+ DONE
+ } state;
+
+ s_core_mem s (
+ .address(s_addr),
+ .clock(clk),
+ .data(s_wrdata),
+ .wren(s_wren),
+ .q(s_rddata)
+ );
+
+ init i (
+ .clk,
+ .rst_n,
+ .en(i_en),
+ .rdy(i_rdy),
+ .addr(i_addr),
+ .wrdata(i_wrdata),
+ .wren(i_wren)
+ );
+
+ ksa k (
+ .clk,
+ .rst_n,
+ .en(k_en),
+ .rdy(k_rdy),
+ .key,
+ .addr(k_addr),
+ .rddata(s_rddata),
+ .wrdata(k_wrdata),
+ .wren(k_wren)
+ );
+
+ prga p (
+ .clk,
+ .rst_n,
+ .en(p_en),
+ .rdy(p_rdy),
+ .key,
+ .s_addr(p_s_addr),
+ .s_rddata,
+ .s_wrdata(p_s_wrdata),
+ .s_wren(p_s_wren),
+ .ct_addr(p_ct_addr),
+ .ct_rddata,
+ .pt_addr(p_pt_addr),
+ .pt_rddata,
+ .pt_wrdata(p_pt_wrdata),
+ .pt_wren(p_pt_wren)
+ );
+
+ always_ff @(posedge clk) begin: fsm
+ if (~rst_n) begin
+ state <= IDLE;
+ end else unique case (state)
+ IDLE: if (en) state <= INIT_BEGIN;
+ INIT_BEGIN: if (i_rdy) state <= INIT;
+ INIT: if (i_rdy) state <= KSA_BEGIN;
+ KSA_BEGIN: if (k_rdy) state <= KSA;
+ KSA: if (k_rdy) state <= PRGA_BEGIN;
+ PRGA_BEGIN: if (p_rdy) state <= PRGA;
+ PRGA: if (p_rdy) state <= DONE;
+ DONE: state <= DONE;
+ default: state <= IDLE;
+ endcase
+ end: fsm
+
+ always_comb begin: controller
+ rdy = '0;
+
+ i_en = '0;
+ k_en = '0;
+ p_en = '0;
+
+ s_wren = '0;
+ s_addr = '0;
+ s_wrdata = '0;
+
+ ct_addr = '0;
+
+ pt_wren = '0;
+ pt_addr = '0;
+ pt_wrdata = '0;
+
+ unique case (state)
+ IDLE: rdy = '1;
+ INIT_BEGIN: i_en = i_rdy;
+ INIT: begin
+ s_wren = i_wren;
+ s_addr = i_addr;
+ s_wrdata = i_wrdata;
+ end
+ KSA_BEGIN: k_en = k_rdy;
+ KSA: begin
+ s_wren = k_wren;
+ s_addr = k_addr;
+ s_wrdata = k_wrdata;
+ end
+ PRGA_BEGIN: p_en = p_rdy;
+ PRGA: begin
+ s_wren = p_s_wren;
+ s_addr = p_s_addr;
+ s_wrdata = p_s_wrdata;
+ ct_addr = p_ct_addr;
+ pt_wren = p_pt_wren;
+ pt_addr = p_pt_addr;
+ pt_wrdata = p_pt_wrdata;
+ end
+ DONE: rdy = '1;
+ default: begin end
+ endcase
+ end: controller
+
+endmodule: arc4