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 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ hdl/top.sv | 220 +-------------------------------------------------------- 2 files changed, 232 insertions(+), 219 deletions(-) create mode 100644 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 diff --git a/hdl/top.sv b/hdl/top.sv index 0aebd77..1d77216 100644 --- a/hdl/top.sv +++ b/hdl/top.sv @@ -1,9 +1,6 @@ `include "util.svh" module top - #( ADDR_BITS = 14 - , DATA_BITS = 12 - ) ( input bit native_clk // verilator public , input bit reset_n // verilator public ); @@ -21,224 +18,9 @@ clock , .reset(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 +core cpu ( .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