summaryrefslogtreecommitdiff
path: root/hdl/top.sv
diff options
context:
space:
mode:
Diffstat (limited to 'hdl/top.sv')
-rw-r--r--hdl/top.sv69
1 files changed, 47 insertions, 22 deletions
diff --git a/hdl/top.sv b/hdl/top.sv
index c87cc29..ac8342e 100644
--- a/hdl/top.sv
+++ b/hdl/top.sv
@@ -18,7 +18,9 @@ bit mem_valid;
18bit mem_write; 18bit mem_write;
19bit [ADDR_BITS-1:0] mem_address; 19bit [ADDR_BITS-1:0] mem_address;
20bit [DATA_BITS-1:0] mem_write_data; 20bit [DATA_BITS-1:0] mem_write_data;
21bit [DATA_BITS-1:0] mem_read_data; 21
22bit mem_read_valid; `define mem_read_valid `past(mem_read_valid)
23bit [DATA_BITS-1:0] mem_read_data; `define mem_read_data `past(mem_read_data)
22 24
23mem 25mem
24 #( .ADDR_BITS(ADDR_BITS) 26 #( .ADDR_BITS(ADDR_BITS)
@@ -27,12 +29,15 @@ mem
27 ) 29 )
28 memory 30 memory
29 ( .clk(clk) 31 ( .clk(clk)
32 , .reset(reset)
30 33
31 , .ready(mem_ready) 34 , .ready(mem_ready)
32 , .valid(mem_valid) 35 , .valid(mem_valid)
33 , .address(mem_address) 36 , .address(mem_address)
34 , .write(mem_write) 37 , .write(mem_write)
35 , .write_data(mem_write_data) 38 , .write_data(mem_write_data)
39
40 , .read_valid(mem_read_valid)
36 , .read_data(mem_read_data) 41 , .read_data(mem_read_data)
37 ); 42 );
38 43
@@ -68,7 +73,9 @@ bit [DATA_BITS-1:0] idx;
68enum 73enum
69 { FETCH 74 { FETCH
70 , DECODE 75 , DECODE
76 , AGEN
71 , MEMORY 77 , MEMORY
78 , HALT
72 } state; 79 } state;
73 80
74always_ff @(posedge clk) begin 81always_ff @(posedge clk) begin
@@ -82,7 +89,7 @@ always_ff @(posedge clk) begin
82 idx = 0; 89 idx = 0;
83 state = state.first; 90 state = state.first;
84 end else begin 91 end else begin
85 `ifdef DEBUG $display("s=%0d pc=%x (acc=%x idx=%x)", state, pc, acc, idx); `endif 92 `ifdef DEBUG $display("s=%0d pc=%x (acc=%x idx=%x) (mem %b:%x)", state, pc, acc, idx, `mem_read_valid, `mem_read_data); `endif
86 if (`tx_ready) tx_valid = 0; 93 if (`tx_ready) tx_valid = 0;
87 94
88 case (state) 95 case (state)
@@ -98,51 +105,64 @@ always_ff @(posedge clk) begin
98 end 105 end
99 106
100 DECODE: begin 107 DECODE: begin
108 if (`mem_read_valid) begin
109 mem_valid = 0;
110 mem_write = 0;
111 state = FETCH;
112 {opcode, operand} = `mem_read_data;
113 `ifdef DEBUG $display("\tdecode %x:%x", opcode, operand); `endif
114 case (opcode)
115 'h0: acc = {{4{operand[7]}}, operand};
116 'h1: state = AGEN;
117 'h2: state = AGEN;
118 'h3: if (acc != operand) ++pc;
119 'h4: pc = pc + {{4{operand[7]}}, operand};
120 'hf: begin
121 if (operand[0]) ++acc;
122 if (operand[1]) --acc;
123 if (operand[2]) ++idx;
124 if (operand[3]) --idx;
125 if (operand[4]) {idx, acc} = {acc, idx};
126 if (operand[5]) idx = acc;
127 if (operand[6]) state = MEMORY;
128 if (operand[7]) state = HALT;
129 end
130 endcase
131 end
132 end
133
134 AGEN: begin
101 mem_valid = 0; 135 mem_valid = 0;
102 mem_write = 0; 136 mem_write = 0;
103 state = FETCH; 137 state = FETCH;
104 {opcode, operand} = mem_read_data; 138 `ifdef DEBUG $display("\tagen"); `endif
105 `ifdef DEBUG $display("\tdecode %x:%x", opcode, operand); `endif
106 case (opcode) 139 case (opcode)
107 'h0: acc = {{4{operand[7]}}, operand};
108 'h1: begin 140 'h1: begin
109 mem_valid = 1; 141 mem_valid = 1;
110 mem_address = idx + operand; 142 mem_address = idx + operand;
111 state = MEMORY; 143 state = `mem_ready ? MEMORY : AGEN;
112 end 144 end
113 'h2: begin 145 'h2: begin
114 mem_valid = 1; 146 mem_valid = 1;
115 mem_address = idx + operand; 147 mem_address = idx + operand;
116 mem_write = 1; 148 mem_write = 1;
117 mem_write_data = acc; 149 mem_write_data = acc;
118 if (! `mem_ready) state = MEMORY; 150 state = `mem_ready ? FETCH : AGEN;
119 end
120 'h3: if (acc != operand) ++pc;
121 'h4: pc = pc + {{4{operand[7]}}, operand};
122 'hf: begin
123 if (operand[0]) ++acc;
124 if (operand[1]) --acc;
125 if (operand[2]) ++idx;
126 if (operand[3]) --idx;
127 if (operand[4]) {idx, acc} = {acc, idx};
128 if (operand[5]) idx = acc;
129 if (operand[6]) state = MEMORY;
130 if (operand[7]) state = DECODE;
131 end 151 end
132 endcase 152 endcase
133 end 153 end
134 154
135 MEMORY: begin 155 MEMORY: begin
136 `ifdef DEBUG $display("\tstall"); `endif
137 if (`mem_ready) begin 156 if (`mem_ready) begin
138 mem_valid = 0; 157 mem_valid = 0;
139 mem_write = 0; 158 mem_write = 0;
140 end 159 end
141 state = FETCH; 160 state = FETCH;
161 `ifdef DEBUG $display("\tstall"); `endif
142 case (opcode) 162 case (opcode)
143 'h1: begin 163 'h1: begin
144 if (`mem_ready) begin 164 if (`mem_read_valid) begin
145 acc = mem_read_data; 165 acc = `mem_read_data;
146 end else begin 166 end else begin
147 state = MEMORY; 167 state = MEMORY;
148 end 168 end
@@ -159,6 +179,11 @@ always_ff @(posedge clk) begin
159 end 179 end
160 endcase 180 endcase
161 end 181 end
182
183 HALT: begin
184 $display("Reached halt state.");
185 $finish;
186 end
162 endcase 187 endcase
163 188
164 `ifdef DEBUG if (mem_valid) $display("\tmem addr=%x w=%b", mem_address, mem_write); `endif 189 `ifdef DEBUG if (mem_valid) $display("\tmem addr=%x w=%b", mem_address, mem_write); `endif