From 8ce2d2a993e703e90960eea5a8a2fa972a76e498 Mon Sep 17 00:00:00 2001 From: Raphael Jacquot Date: Sat, 2 Mar 2019 13:22:09 +0100 Subject: [PATCH] implement more of the bus controller --- run.sh | 3 +- saturn_bus_controller.v | 121 ++++++++++++++++++++++++++++++++-- saturn_control_unit.v | 141 ++++++++++++++++++++++++++++++++++++++++ saturn_debugger.v | 56 ++++++++++++++++ saturn_def_buscmd.v | 22 +++---- saturn_top.v | 13 ++-- 6 files changed, 334 insertions(+), 22 deletions(-) create mode 100644 saturn_control_unit.v create mode 100644 saturn_debugger.v diff --git a/run.sh b/run.sh index 8f5e9a8..b54303d 100755 --- a/run.sh +++ b/run.sh @@ -13,7 +13,8 @@ iverilog -v -Wall -DSIM -o z_saturn_test.iv -s saturn_top \ saturn_top.v \ saturn_bus.v saturn_hp48gx_rom.v \ - saturn_bus_controller.v + saturn_bus_controller.v saturn_debugger.v \ + saturn_control_unit.v IVERILOG_STATUS=$? #./mask_gen_tb echo "--------------------------------------------------------------------" diff --git a/saturn_bus_controller.v b/saturn_bus_controller.v index c6e7364..cc30479 100644 --- a/saturn_bus_controller.v +++ b/saturn_bus_controller.v @@ -50,22 +50,131 @@ input wire [3:0] i_bus_nibble_in; output wire [0:0] o_debug_cycle; output wire [0:0] o_halt; +/************************************************************************************************** + * + * master control unit + * + *************************************************************************************************/ +saturn_control_unit control_unit ( + .i_clk (i_clk), + .i_reset (i_reset), + .i_phases (i_phases), + .i_phase (i_phase), + .i_cycle_ctr (i_cycle_ctr), + .i_debug_cycle (dbg_debug_cycle), + .o_program_address (ctrl_unit_prog_addr), + .o_program_data (ctrl_unit_prog_data), + .o_error (ctrl_unit_error) +); + +wire [0:0] ctrl_unit_error; +wire [4:0] ctrl_unit_prog_addr; +wire [4:0] ctrl_unit_prog_data; + +/************************************************************************************************** + * + * debugger module + * + *************************************************************************************************/ + +saturn_debugger debugger ( + .i_clk (i_clk), + .i_reset (i_reset), + .i_phases (i_phases), + .i_phase (i_phase), + .i_cycle_ctr (i_cycle_ctr), + .o_debug_cycle (dbg_debug_cycle) +); + +wire [0:0] dbg_debug_cycle; +assign o_debug_cycle = dbg_debug_cycle; + +/************************************************************************************************** + * + * the bus controller module + * + *************************************************************************************************/ + +/* + * local registers + */ reg [0:0] bus_error; -initial bus_error = 0; +/* + * program list for the bus controller + * this is used for the control unit to send the bus controller + * the list of things that need to be done for long sequences + */ +reg [4:0] bus_prog_addr; +reg [4:0] bus_program[0:31]; -// this should come from the debugger -assign o_debug_cycle = 1'b0; -assign o_halt = bus_error; +always @(*) begin + $write("BUSCTRL %0d: [%d] write prog %d : %5b\n", i_phase, i_cycle_ctr, ctrl_unit_prog_addr, ctrl_unit_prog_data); + bus_program[ctrl_unit_prog_addr] = ctrl_unit_prog_data; +end + +/* + * this should come from the debugger + */ + +assign o_halt = bus_error || ctrl_unit_error; + +initial begin + bus_error = 1'b0; + bus_prog_addr = 5'd31; +end + +/* + * bus chronograms + * + * The bus works on a 4 phase system + * + */ always @(posedge i_clk) begin if (!o_debug_cycle) begin - + case (i_phases) + 4'b0001: + begin + /* + * in this phase, we can send a command or data from the processor + */ + if (bus_prog_addr != ctrl_unit_prog_addr) begin + $write("BUSCTRL %0d: [%d] %d : %5b ", i_phase, i_cycle_ctr, bus_prog_addr + 5'd1, bus_program[bus_prog_addr + 5'd1]); + if (bus_program[bus_prog_addr + 5'd1][4]) begin + $write("CMD :"); + end + else $write("DATA : %h", bus_program[bus_prog_addr + 5'd1][3:0]); + $write("\n"); + bus_prog_addr <= bus_prog_addr + 5'd1; + end + end + 4'b0010: + begin + /* + * this phase is reserved for reading data from the bus + */ + end + 4'b0100: + begin + /* + * this phase is when the instruction decoder does it's job + */ + end + 4'b1000: + begin + /* + * instructions that can be handled in one clock are done here, otherwise, we start the ALU + */ + end + default: begin end // other states should not exist + endcase end if (i_reset) begin - bus_error <= 1'b0; + bus_error <= 1'b0; + bus_prog_addr <= 5'd31; end end diff --git a/saturn_control_unit.v b/saturn_control_unit.v new file mode 100644 index 0000000..53272a2 --- /dev/null +++ b/saturn_control_unit.v @@ -0,0 +1,141 @@ +/* + (c) Raphaël Jacquot 2019 + + This file is part of hp_saturn. + + hp_saturn is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + any later version. + + hp_saturn is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Foobar. If not, see . + + */ + +`default_nettype none + +`include "saturn_def_buscmd.v" + +module saturn_control_unit ( + i_clk, + i_reset, + i_phases, + i_phase, + i_cycle_ctr, + i_debug_cycle, + + o_program_data, + o_program_address, + + o_error +); + +input wire [0:0] i_clk; +input wire [0:0] i_reset; +input wire [3:0] i_phases; +input wire [1:0] i_phase; +input wire [31:0] i_cycle_ctr; +input wire [0:0] i_debug_cycle; + +output reg [4:0] o_program_data; +output reg [4:0] o_program_address; + +output wire [0:0] o_error; +assign o_error = control_unit_error; + +/************************************************************************************************** + * + * cpu modules go here + * + *************************************************************************************************/ + + +/************************************************************************************************** + * + * the control unit + * + *************************************************************************************************/ + +reg [0:0] control_unit_error; +reg [0:0] just_reset; +reg [0:0] control_unit_ready; +reg [4:0] bus_prog_addr; + +initial begin + o_program_address = 5'd31; + o_program_data = 5'd0; + control_unit_error = 1'b0; + just_reset = 1'b1; + control_unit_ready = 1'b0; + bus_prog_addr = 5'd0; +end + +always @(posedge i_clk) begin + + if (!i_debug_cycle && just_reset && i_phases[3]) begin + /* this happend right after reset */ +`ifdef SIM + if (!i_reset) + $display("CTRL %0d: [%d] we are in the control unit", i_phase, i_cycle_ctr); +`endif + just_reset <= 1'b0; + o_program_data <= {1'b1, `BUSCMD_LOAD_PC }; +`ifdef SIM + $display("CTRL %0d: [%d] pushing LOAD_PC command to pos %d", i_phase, i_cycle_ctr, bus_prog_addr); +`endif + /* push the current program pointer out, + * increment the program pointer + */ + o_program_address <= bus_prog_addr; + bus_prog_addr <= bus_prog_addr + 1; + end + + /* loop to fill the initial PC value in the program */ + if (!i_debug_cycle && !control_unit_ready && (bus_prog_addr != 5'b0)) begin + o_program_data <= 5'b0; + o_program_address <= bus_prog_addr; + bus_prog_addr <= bus_prog_addr + 1; +`ifdef SIM + $write("CTRL %0d: [%d] pushing ADDR[%0d] = 0", i_phase, i_cycle_ctr, bus_prog_addr); +`endif + if (bus_prog_addr == 5'd5) begin + control_unit_ready <= 1'b1; +`ifdef SIM + $write(" done"); +`endif + end +`ifdef SIM + $write("\n"); +`endif + end + + /* this happend otherwise */ + if (!i_debug_cycle && control_unit_ready) begin + +`ifdef SIM + $display("CTRL %0d: [%d] starting to do things", i_phase, i_cycle_ctr); +`endif + control_unit_error <= 1'b1; + end + + if (i_reset) begin + o_program_address <= 5'd31; + o_program_data <= 5'd0; + control_unit_error <= 1'b0; + just_reset <= 1'b1; + control_unit_ready <= 1'b0; + bus_prog_addr <= 5'd0; + end + +end + +endmodule + + + diff --git a/saturn_debugger.v b/saturn_debugger.v new file mode 100644 index 0000000..326b74f --- /dev/null +++ b/saturn_debugger.v @@ -0,0 +1,56 @@ +/* + (c) Raphaël Jacquot 2019 + + This file is part of hp_saturn. + + hp_saturn is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + any later version. + + hp_saturn is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Foobar. If not, see . + + */ + +`default_nettype none + +module saturn_debugger ( + i_clk, + i_reset, + i_phases, + i_phase, + i_cycle_ctr, + + o_debug_cycle +); + +input wire [0:0] i_clk; +input wire [0:0] i_reset; +input wire [3:0] i_phases; +input wire [1:0] i_phase; +input wire [31:0] i_cycle_ctr; + +output reg [0:0] o_debug_cycle; + +initial begin + o_debug_cycle = 1'b0; +end + + +always @(posedge i_clk) begin + + + if (i_reset) begin + o_debug_cycle <= 1'b0; + end + +end + +endmodule + diff --git a/saturn_def_buscmd.v b/saturn_def_buscmd.v index 81f7554..3d11ca2 100644 --- a/saturn_def_buscmd.v +++ b/saturn_def_buscmd.v @@ -10,16 +10,16 @@ `ifndef _BUSCMD `define _BUSCMD -`define BUSCMD_NOP 0 -`define BUSCMD_ID 1 -`define BUSCMD_PC_READ 2 -`define BUSCMD_DP_READ 3 -`define BUSCMD_PC_WRITE 4 -`define BUSCMD_DP_WRITE 5 -`define BUSCMD_LOAD_PC 6 -`define BUSCMD_LOAD_DP 7 -`define BUSCMD_CONFIGURE 8 -`define BUSCMD_UNCONFIGURE 9 -`define BUSCMD_RESET 15 +`define BUSCMD_NOP 4'h0 +`define BUSCMD_ID 4'h1 +`define BUSCMD_PC_READ 4'h2 +`define BUSCMD_DP_READ 4'h3 +`define BUSCMD_PC_WRITE 4'h4 +`define BUSCMD_DP_WRITE 4'h5 +`define BUSCMD_LOAD_PC 4'h6 +`define BUSCMD_LOAD_DP 4'h7 +`define BUSCMD_CONFIGURE 4'h8 +`define BUSCMD_UNCONFIGURE 4'h9 +`define BUSCMD_RESET 4'hF `endif diff --git a/saturn_top.v b/saturn_top.v index 33763bc..849e747 100644 --- a/saturn_top.v +++ b/saturn_top.v @@ -34,16 +34,21 @@ reg [0:0] reset; wire [0:0] halt; initial begin - $display("starting the simulation"); - clk <= 0; - reset <= 1; + $display("TOP : starting the simulation"); + clk = 0; + reset = 1; @(posedge clk); @(posedge clk); @(posedge clk); - reset <= 0; + reset = 0; + $display("TOP : reset done, waiting for instructions"); @(posedge halt); + $display("TOP : instructed to stop, halt is %b", halt); $finish; end +always + #10 clk = (clk === 1'b0); + endmodule `endif \ No newline at end of file