From b95b2635a4d1c9b9a87588e54995cc5cdaada79f Mon Sep 17 00:00:00 2001 From: Julian Blake Kongslie Date: Sun, 18 Apr 2021 14:46:30 -0700 Subject: Move the core logic out of the top module. --- hdl/core.sv | 231 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 hdl/core.sv (limited to 'hdl/core.sv') diff --git a/hdl/core.sv b/hdl/core.sv new file mode 100644 index 0000000..919dac9 --- /dev/null +++ b/hdl/core.sv @@ -0,0 +1,231 @@ +`include "util.svh" + +module core + #( ADDR_BITS = 14 + , DATA_BITS = 12 + ) + ( input bit clk + , input bit reset + ); + +bit mem_ready; +bit mem_valid; +bit mem_write; +bit [ADDR_BITS-1:0] mem_address; +bit [DATA_BITS-1:0] mem_write_data; + +bit mem_read_valid; +bit [DATA_BITS-1:0] mem_read_data; + +mem + #( .ADDR_BITS(ADDR_BITS) + , .DATA_BITS(DATA_BITS) + , .INIT_FILE("mem/mem.hex") + ) + memory + ( .clk(clk) + , .reset(reset) + + , .ready(mem_ready) + , .valid(mem_valid) + , .address(mem_address) + , .write(mem_write) + , .write_data(mem_write_data) + + , .read_valid(mem_read_valid) + , .read_data(mem_read_data) + ); + +bit rx_ready; +bit rx_valid; +bit [7:0] rx_data; + +bit tx_ready; +bit tx_valid; +bit [7:0] tx_data; + +jtag_uart + #( .INSTANCE(0) + ) uart0 + ( .clk(clk) + , .reset(reset) + + , .rx_ready(rx_ready) + , .rx_valid(rx_valid) + , .rx_data(rx_data) + + , .tx_ready(tx_ready) + , .tx_valid(tx_valid) + , .tx_data(tx_data) + ); + +bit [ADDR_BITS-1:0] pc; +bit [3:0] opcode; +bit [7:0] operand; +bit [DATA_BITS-1:0] acc; + +bit [ADDR_BITS-1:0] address; +bit [DATA_BITS-1:0] sign_extended_operand; + +enum + { FETCH + , DECODE + , INDIRECT + , INDIRECTED + , AGEN + , MEMORY + , HALT + } state; + +always_ff @(posedge clk) begin + if (reset) begin + mem_valid = 0; + rx_ready = 0; + tx_valid = 0; + tx_data = 0; + pc = 0; + acc = 0; + state = state.first; + end else begin + if (`lag(tx_ready)) tx_valid = 0; + + case (state) + FETCH: begin + mem_valid = 1; + mem_address = pc; + mem_write = 0; + if (`lag(mem_ready)) begin + state = DECODE; + ++pc; + end + end + + DECODE: begin + mem_valid = 0; + mem_write = 0; + if (`lag(mem_read_valid)) begin + state = FETCH; + {opcode, operand} = `lag(mem_read_data); + sign_extended_operand = {{(DATA_BITS-8){operand[7]}}, operand}; + case (opcode) + 'h0: begin + if (operand[0]) acc = 0; + if (operand[1]) ++acc; + if (operand[2]) --acc; + if (operand[6]) state = MEMORY; + if (operand[7]) begin + rx_ready = 1; + state = MEMORY; + end + if (operand == 0) state = HALT; + end + 'h1: acc = sign_extended_operand; + 'h2, 'h3: begin + address = {7'b0, operand[6:0]}; + state = operand[7] ? INDIRECT : AGEN; + end + 'h4: if (acc != sign_extended_operand) ++pc; + 'h5: begin + if (operand[7]) begin + address = {7'b0, operand[6:0]}; + state = INDIRECT; + end else begin + pc = pc + {{(ADDR_BITS-7){operand[6]}}, operand[6:0]}; + end + end + 'h6: begin + mem_write_data = acc % 10 + 'h30; + acc = acc / 10; + address = {7'b0, operand[6:0]}; + state = operand[7] ? INDIRECT : AGEN; + end + endcase + end + end + + INDIRECT: begin + mem_valid = 1; + mem_write = 0; + mem_address = address; + state = `lag(mem_ready) ? INDIRECTED : INDIRECT; + end + + INDIRECTED: begin + if (`lag(mem_ready)) begin + mem_valid = 0; + mem_write = 0; + end + if (`lag(mem_read_valid)) begin + address = {{(ADDR_BITS - DATA_BITS){1'b0}}, `lag(mem_read_data)}; + state = AGEN; + end + end + + AGEN: begin + mem_valid = 0; + mem_write = 0; + state = FETCH; + case (opcode) + 'h2: begin + mem_valid = 1; + mem_address = address; + state = `lag(mem_ready) ? MEMORY : AGEN; + end + 'h3: begin + mem_valid = 1; + mem_address = address; + mem_write = 1; + mem_write_data = acc; + state = `lag(mem_ready) ? FETCH : AGEN; + end + 'h5: pc = address; + 'h6: begin + mem_valid = 1; + mem_address = address; + mem_write = 1; + state = `lag(mem_ready) ? FETCH : AGEN; + end + endcase + end + + MEMORY: begin + if (`lag(mem_ready)) begin + mem_valid = 0; + mem_write = 0; + end + state = FETCH; + case (opcode) + 'h0: begin + if (operand[6]) begin + if (tx_valid) begin + state = MEMORY; + end else begin + tx_valid = 1; + tx_data = acc[7:0]; + end + end + if (operand[7]) begin + if (`lag(rx_valid)) begin + rx_ready = 0; + acc = {{(DATA_BITS-8){1'b0}}, `lag(rx_data)}; + end else begin + state = MEMORY; + end + end + end + 'h2: begin + if (`lag(mem_read_valid)) begin + acc = acc + `lag(mem_read_data); + end else begin + state = MEMORY; + end + end + endcase + end + + HALT: $finish; + endcase + end +end + +endmodule -- cgit v1.2.3