summaryrefslogtreecommitdiff
path: root/hdl
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--hdl/jtag_uart.sv84
-rw-r--r--hdl/top.sv89
-rw-r--r--hdl/util.svh5
3 files changed, 178 insertions, 0 deletions
diff --git a/hdl/jtag_uart.sv b/hdl/jtag_uart.sv
new file mode 100644
index 0000000..ad4665e
--- /dev/null
+++ b/hdl/jtag_uart.sv
@@ -0,0 +1,84 @@
1`include "util.svh"
2
3module jtag_uart
4 #( INSTANCE = 0
5
6 , RX_FIFO_BITS = 6
7 , TX_FIFO_BITS = 6
8 )
9 ( input bit clk
10 , input bit reset
11
12 , input bit rx_ready `define rx_ready `past(rx_ready)
13 , output bit rx_valid
14 , output bit [7:0] rx_data
15
16 , output bit tx_ready
17 , input bit tx_valid `define tx_valid `past(tx_valid)
18 , input bit [7:0] tx_data `define tx_data `past(tx_data)
19 );
20
21`ifdef SYNTHESIS
22
23alt_jtag_atlantic
24 #( .INSTANCE_ID(INSTANCE)
25 , .LOG2_RXFIFO_DEPTH(RX_FIFO_BITS)
26 , .LOG2_TXFIFO_DEPTH(TX_FIFO_BITS)
27 , .SLD_AUTO_INSTANCE_INDEX("NO")
28 ) real_jtag
29 ( .clk(clk)
30 , .rst_n(!reset)
31 , .r_dat(tx_data)
32 , .r_val(tx_valid)
33 , .r_ena(tx_ready)
34 , .t_dat(rx_data)
35 , .t_dav(rx_ready)
36 , .t_ena(rx_valid)
37 );
38
39`else
40
41bit [7:0] sim_rx_rom [0:(1<<16)-1];
42initial $readmemh("mem/jtag_uart.hex", sim_rx_rom);
43
44bit [15:0] sim_rx_addr;
45
46bit tx_b_valid;
47bit [7:0] tx_b_data;
48
49always_ff @(posedge clk) begin
50 if (reset) begin
51 rx_valid = 0;
52 tx_ready = 0;
53 sim_rx_addr = 0;
54 tx_b_valid = 0;
55 end else begin
56 automatic bit [7:0] sim_rx_data = sim_rx_rom[sim_rx_addr];
57
58 // RX logic
59 if (`rx_ready) rx_valid = 0;
60 if (!rx_valid && (sim_rx_data != 0)) begin
61`ifdef JTAG_UART_LOCAL_ECHO
62 $write("%s", sim_rx_data);
63`endif
64 rx_valid = 1;
65 rx_data = sim_rx_data;
66 ++sim_rx_addr;
67 end
68
69 // TX logic
70 if (tx_ready && `tx_valid) begin
71 tx_b_valid = 1;
72 tx_b_data = `tx_data;
73 end
74 if (tx_b_valid) begin
75 $write("%s", tx_b_data);
76 tx_b_valid = 0;
77 end
78 tx_ready = !tx_b_valid;
79 end
80end
81
82`endif
83
84endmodule
diff --git a/hdl/top.sv b/hdl/top.sv
new file mode 100644
index 0000000..8524b63
--- /dev/null
+++ b/hdl/top.sv
@@ -0,0 +1,89 @@
1`include "util.svh"
2
3module top
4 #( ADDR_BITS = 14
5 , DATA_BITS = 12
6 )
7 ( input bit clk // verilator public
8 , input bit reset_n // verilator public
9 );
10
11bit reset = 0;
12bit have_reset = 0;
13always_ff @(posedge clk) if (reset) have_reset <= 1;
14assign reset = !reset_n || !have_reset;
15
16bit [DATA_BITS-1:0] mem [0:(1<<ADDR_BITS)-1];
17initial $readmemh("mem/mem.hex", mem);
18
19bit rx_ready;
20bit rx_valid;
21bit [7:0] rx_data;
22
23bit tx_ready;
24bit tx_valid;
25bit [7:0] tx_data;
26
27jtag_uart
28 #( .INSTANCE(0)
29 ) uart0
30 ( .clk(clk)
31 , .reset(reset)
32
33 , .rx_ready(rx_ready)
34 , .rx_valid(rx_valid) `define rx_valid `past(rx_valid)
35 , .rx_data(rx_data) `define rx_data `past(rx_data)
36
37 , .tx_ready(tx_ready) `define tx_ready `past(tx_ready)
38 , .tx_valid(tx_valid)
39 , .tx_data(tx_data)
40 );
41
42bit [DATA_BITS-1:0] pc;
43bit [3:0] opcode;
44bit [7:0] operand;
45bit [DATA_BITS-1:0] acc;
46
47enum
48 { FETCH
49 , DECODE
50 } state;
51
52always_ff @(posedge clk) begin
53 if (reset) begin
54 rx_ready = 0;
55 tx_valid = 0;
56 tx_data = 0;
57 pc = 0;
58 acc = 0;
59 state = state.first;
60 end else begin
61 if (`tx_ready) tx_valid = 0;
62
63 case (state)
64 FETCH: begin
65 {opcode, operand} = mem[{2'b0, pc}];
66 ++pc;
67 state = DECODE;
68 end
69
70 DECODE: begin
71 state = FETCH;
72 case (opcode)
73 'b000: acc = {{4{operand[7]}}, operand};
74 'b001: begin
75 if (tx_valid) begin
76 state = DECODE;
77 end else begin
78 tx_valid = 1;
79 tx_data = acc[7:0];
80 end
81 end
82 'b111: state = DECODE;
83 endcase
84 end
85 endcase
86 end
87end
88
89endmodule
diff --git a/hdl/util.svh b/hdl/util.svh
new file mode 100644
index 0000000..ddba543
--- /dev/null
+++ b/hdl/util.svh
@@ -0,0 +1,5 @@
1`ifdef SYNTHESIS
2`define past(x) x
3`else
4`define past(x) $past(x)
5`endif