time to start over, this this is broken beyond fiddling

This commit is contained in:
Raphael Jacquot 2019-02-24 21:54:15 +01:00
parent 49b20d72f3
commit 570807cf61
30 changed files with 1057 additions and 756 deletions

View file

@ -1,49 +0,0 @@
`ifndef _SATURN_ALU
`define _SATURN_ALU
/**************************************************************************************************
*
* Bus manager
*
*
*
*/
module saturn_alu (
// inputs
input strobe,
input reset,
input [19:0] address,
input [3:0] command,
input [3:0] nibble_in,
// outputs
output [3:0] nibble_out,
output bus_error
);
// processor registers
reg [19:0] PC;
reg [3:0] P;
reg [15:0] ST;
reg [3:0] HST;
reg Carry;
reg [19:0] RSTK[0:7];
reg [19:0] D0;
reg [19:0] D1;
reg [63:0] A;
reg [63:0] B;
reg [63:0] C;
reg [63:0] D;
reg [63:0] R0;
reg [63:0] R1;
reg [63:0] R2;
reg [63:0] R3;
reg [63:0] R4;
endmodule
`endif

View file

@ -19,12 +19,14 @@
*/
`default_nettype none //
`include "saturn_alu_pc.v"
`include "saturn_alu_registers.v"
`include "def-alu.v"
`ifndef _SATURN_ALU
`define _SATURN_ALU
`include "def-alu.v"
`default_nettype none //
`ifdef SIM
// `define ALU_DEBUG_DBG
@ -41,6 +43,8 @@ module saturn_alu (
i_phases,
i_cycle_ctr,
i_stalled,
o_en_cycle_cnt,
o_reg_dump,
o_bus_address,
i_bus_data_ptr,
@ -98,13 +102,16 @@ input wire [0:0] i_reset;
input wire [3:0] i_phases;
input wire [31:0] i_cycle_ctr;
input wire [0:0] i_stalled;
output wire [0:0] o_en_cycle_cnt;
output wire [0:0] o_reg_dump;
wire [0:0] i_reg_dump;
/*
* I/O to the bus controller
*/
/* data to and from the bus controller */
output reg [19:0] o_bus_address;
output wire [19:0] o_bus_address;
input wire [3:0] i_bus_data_ptr;
output reg [3:0] o_bus_data_nibl;
output reg [3:0] o_bus_xfr_cnt;
@ -115,7 +122,7 @@ output reg [3:0] o_bus_nibble_out;
output reg [0:0] o_bus_pc_read;
output reg [0:0] o_bus_dp_read;
output reg [0:0] o_bus_dp_write;
output reg [0:0] o_bus_load_pc;
output wire [0:0] o_bus_load_pc;
output reg [0:0] o_bus_load_dp;
output reg [0:0] o_bus_config;
input wire [0:0] i_bus_done;
@ -159,8 +166,6 @@ output wire [3:0] o_reg_p;
output wire [19:0] o_pc;
assign o_reg_p = P;
assign o_pc = PC;
/*
*
@ -193,7 +198,117 @@ end
wire alu_active;
assign alu_active = !i_reset && !i_stalled;
assign alu_active = !i_reset && !i_stalled && !i_reg_dump;
/*
* this module handles the PC and the RSTK
*
*
*/
saturn_alu_pc pc_management (
.i_clk (i_clk),
.i_reset (i_reset),
.i_stalled (i_stalled),
.i_just_reset (just_reset),
.i_alu_active (alu_active),
.i_cycle_ctr (i_cycle_ctr),
.i_phase (phase),
.i_phase_0 (phase_0),
.i_phase_2 (phase_2),
.i_phase_3 (phase_3),
.i_alu_initializing (alu_initializing),
.i_v_dest_counter_ptr (v_dest_counter_ptr),
.o_bus_address (o_bus_address),
.o_bus_load_pc (o_bus_load_pc),
.i_bus_nibble_in (i_bus_nibble_in),
.i_alu_stall_dec (o_alu_stall_dec),
.i_ins_rtn (i_ins_rtn),
.i_ins_test_go (i_ins_test_go),
.i_push (i_push),
.i_pop (i_pop),
.i_mode_jmp (mode_jmp),
.i_carry (CARRY),
.i_op_jump (op_jump),
.i_op_jmp_rel_2 (op_jmp_rel_2),
.i_op_jmp_rel_3 (op_jmp_rel_3),
.i_op_jmp_rel_4 (op_jmp_rel_4),
.i_op_jmp_abs_5 (op_jmp_abs_5),
.o_do_apply_jump (do_apply_jump),
`ifdef SIM
.o_pc (o_pc),
.o_rstk_ptr (rstk_ptr),
.o_rstk_0 (rstk_0),
.o_rstk_1 (rstk_1),
.o_rstk_2 (rstk_2),
.o_rstk_3 (rstk_3),
.o_rstk_4 (rstk_4),
.o_rstk_5 (rstk_5),
.o_rstk_6 (rstk_6),
.o_rstk_7 (rstk_7)
`else
.o_pc (o_pc)
`endif
);
wire [0:0] do_apply_jump;
`ifdef SIM
wire [2:0] rstk_ptr;
wire [19:0] rstk_0;
wire [19:0] rstk_1;
wire [19:0] rstk_2;
wire [19:0] rstk_3;
wire [19:0] rstk_4;
wire [19:0] rstk_5;
wire [19:0] rstk_6;
wire [19:0] rstk_7;
`endif
/*
* This module handles the data and pointer registers
*
*
*/
saturn_alu_registers registers (
.i_clk (i_clk),
.i_reset (i_reset),
.i_stalled (i_stalled),
.i_phase (phase),
.i_phase_3 (phase_3),
.i_cycle_ctr (i_cycle_ctr),
.i_alu_initializing (alu_initializing),
.i_ins_decoded (i_ins_decoded),
.i_src_ptr (source_counter),
.i_src_1 (i_reg_src1),
.o_src_1_nbl (rp_src_1),
.o_src_1_valid (rp_src_1_valid),
.i_src_2 (i_reg_src2),
.o_src_2_nbl (rp_src_2),
.o_src_2_valid (rp_src_2_valid),
.i_dest_ptr (v_dest_ptr),
.i_dest_1 (i_reg_dest),
.i_dest_1_nbl (rc_res_1),
.i_dest_2 (i_reg_src2),
.i_dest_2_nbl (c_res_2)
`ifdef SIM
,
.i_dbg_src (alu_dbg_src),
.i_dbg_ptr (alu_dbg_ctr[3:0]),
.o_dbg_nbl (alu_dbg_nbl)
`endif
);
/*
*
@ -212,36 +327,29 @@ reg [3:0] f_last;
/* internal pointers */
wire [3:0] rp_src_1;
wire [0:0] rp_src_1_valid;
wire [3:0] rp_src_2;
wire [0:0] rp_src_2_valid;
reg [3:0] p_src1;
reg [3:0] p_src2;
reg [0:0] p_carry;
reg [3:0] c_res1;
reg [3:0] c_res2;
reg [3:0] c_res_1;
reg [3:0] c_res_2;
reg [0:0] c_carry;
reg [0:0] is_zero;
/* alu status */
reg [3:0] rc_res_1;
reg [2:0] rstk_ptr;
/* public registers */
reg [19:0] PC;
reg [3:0] D0[0:4];
reg [3:0] D1[0:4];
//reg [63:0] A;
reg [3:0] A[0:15];
reg [3:0] B[0:15];
reg [3:0] C[0:15];
reg [3:0] D[0:15];
reg [3:0] R0[0:15];
reg [3:0] R1[0:15];
reg [3:0] R2[0:15];
reg [3:0] R3[0:15];
reg [3:0] R4[0:15];
always @(*) begin
rc_res_1 = c_res_1;
if (src1_IMM) rc_res_1 = i_imm_value;
if (src1_P) rc_res_1 = P;
end
reg [0:0] CARRY;
reg [0:0] DEC;
@ -249,10 +357,6 @@ reg [3:0] P;
reg [3:0] HST;
reg [15:0] ST;
reg [19:0] RSTK[0:7];
/******************************************************************************
*
* ALU debug modes
@ -343,7 +447,7 @@ assign start_in_hst_clrmask_mode = alu_start_ev && i_ins_alu_op && op_hst_clrmas
assign start_in_jmp_mode = alu_start_ev && i_ins_alu_op && op_jump && src1_IMM && !mode_set;
assign start_in_alu_mode = alu_start_ev && i_ins_alu_op && !mode_not_alu && !f_mode_alu;
assign o_alu_stall_dec = alu_initializing || i_stalled || stall_modes;
assign o_alu_stall_dec = alu_initializing || i_stalled || stall_modes || i_reg_dump;
/*
@ -507,7 +611,7 @@ always @(posedge i_clk) begin
end
if (do_apply_jump)
$display("ALU %0d: [%d] end of jmp mode", phase, i_cycle_ctr);
$display("ALU %0d: [%d] end of jmp mode", phase, i_cycle_ctr);
/* general ALU mode (when there is no optimization)
*/
@ -517,9 +621,12 @@ always @(posedge i_clk) begin
f_mode_alu <= 1'b1;
end
if (i_reset ||
alu_active && f_mode_xfr && i_bus_done ||
alu_active && f_mode_config && !o_bus_config ||
do_load_pointer_done ||
do_load_register_done ||
do_apply_jump)
begin
@ -667,26 +774,20 @@ always @(posedge i_clk) begin
if (copy_address) begin
// we get the address source from src2
`ifdef SIM
$write("ALU %0d: [%d] xfr_data[%0d] = ", phase, i_cycle_ctr, data_counter);
case (addr_src)
2'b00: begin
$display("A[%0d] %h", source_counter, A[source_counter]);
xfr_data[data_counter] <= A[source_counter];
end
2'b01: begin
$display("C[%0d] %h", source_counter, C[source_counter]);
xfr_data[data_counter] <= C[source_counter];
end
2'b10: begin
$display("D0[%0d] %h", source_counter, D0[source_counter_ptr]);
xfr_data[data_counter] <= D0[source_counter_ptr];
end
2'b11: begin
$display("D1[%0d] %h", source_counter, D1[source_counter_ptr]);
xfr_data[data_counter] <= D1[source_counter_ptr];
end
default: begin end
case (i_reg_src2)
`ALU_REG_A: $write("A");
`ALU_REG_C: $write("C");
`ALU_REG_D0: $write("D0");
`ALU_REG_D1: $write("D1");
default: $write("[invalid register %0d]", i_reg_src2);
endcase
$display("[%0d] %h", source_counter, rp_src_2);
`endif
xfr_data[data_counter] <= rp_src_2;
data_counter <= data_counter + 1;
end
@ -700,8 +801,8 @@ always @(posedge i_clk) begin
// two sources are possible, A and C, a conditional will suffice
if (xfr_data_copy) begin
$display("ALU %0d: [%d] copy data DAT[%b][%2d] <= %c[%2d] %h",
phase, i_cycle_ctr, dest_DAT1, data_counter, src1_A?"A":"C", source_counter, (src1_A)?A[source_counter]:C[source_counter]);
xfr_data[data_counter] <= (src1_A)?A[source_counter]:C[source_counter];
phase, i_cycle_ctr, dest_DAT1, data_counter, src1_A?"A":"C", source_counter, rp_src_1);
xfr_data[data_counter] <= rp_src_1;
data_counter <= data_counter + 1;
end
@ -756,9 +857,12 @@ end
*
*/
// always @(*) begin
always @(posedge i_clk) begin
if (i_reset) begin
c_res_1 <= 4'b0;
end
// end
end
/*
* moduls 4:
@ -776,9 +880,15 @@ reg [3:0] v_dest_counter;
reg [3:0] v_max_counter;
wire [2:0] v_dest_counter_ptr;
wire [1:0] v_dest_counter_hst;
reg [3:0] v_dest_ptr;
assign v_dest_counter_ptr = v_dest_counter[2:0];
assign v_dest_counter_hst = v_dest_counter[1:0];
always @(*) begin
v_dest_ptr = v_dest_counter;
if (op_copy_p_to_c) v_dest_ptr = i_field_start;
end
wire [0:0] do_load_pointer;
wire [0:0] do_load_pointer_done;
wire [0:0] do_load_register;
@ -811,17 +921,6 @@ always @(posedge i_clk) begin
*/
if (!i_reset && alu_initializing) begin
$display("ALU_INIT %0d: [%d] init %0d", phase, i_cycle_ctr, v_dest_counter);
A[v_dest_counter] <= 0;
B[v_dest_counter] <= 0;
C[v_dest_counter] <= 0;
D[v_dest_counter] <= 0;
D0[v_dest_counter_ptr] <= 0;
D1[v_dest_counter_ptr] <= 0;
R0[v_dest_counter] <= 0;
R1[v_dest_counter] <= 0;
R2[v_dest_counter] <= 0;
R3[v_dest_counter] <= 0;
R4[v_dest_counter] <= 0;
ST[v_dest_counter] <= 0;
HST[v_dest_counter_hst] <= 0;
alu_initializing <= (v_dest_counter != 15);
@ -839,18 +938,17 @@ always @(posedge i_clk) begin
if (do_load_pointer) begin
$display("ALU %0d: [%d] loading pointer D%b[%0d] <= %h", phase, i_cycle_ctr, dest_D1, v_dest_counter, i_bus_nibble_in);
case (dest_D1)
0: D0[v_dest_counter_ptr] <= i_bus_nibble_in;
1: D0[v_dest_counter_ptr] <= i_bus_nibble_in;
default: begin end
endcase
v_dest_counter <= v_dest_counter + 1;
// case (dest_D1)
// 0: D0[v_dest_counter_ptr] <= i_bus_nibble_in;
// 1: D0[v_dest_counter_ptr] <= i_bus_nibble_in;
// default: begin end
// endcase
v_dest_counter <= v_dest_counter + 1;
end
if (do_load_pointer_done) begin
$display("ALU %0d: [%d] resetting variables after loading pointer", phase, i_cycle_ctr);
v_dest_counter <= 0;
f_mode_load_ptr <= 0;
end
/*
@ -868,11 +966,11 @@ always @(posedge i_clk) begin
if (do_load_register) begin
$display("ALU %0d: [%d] loading register %c[%0d] <= %h", phase, i_cycle_ctr, dest_A?"A":"C", v_dest_counter, i_bus_nibble_in);
case (dest_C)
0: A[v_dest_counter] <= i_bus_nibble_in;
1: C[v_dest_counter] <= i_bus_nibble_in;
default: begin end
endcase
// case (dest_C)
// 0: A[v_dest_counter] <= i_bus_nibble_in;
// 1: C[v_dest_counter] <= i_bus_nibble_in;
// default: begin end
// endcase
v_dest_counter <= v_dest_counter + 1;
end
@ -893,7 +991,8 @@ always @(posedge i_clk) begin
if (start_in_p_mode && op_copy_p_to_c) begin
$display("ALU %0d: [%d] C=P %h", phase, i_cycle_ctr, i_field_start);
C[i_field_start] <= P;
v_dest_counter <= i_field_start;
// C[i_field_start] <= P;
end
/* ST=[01] <bit>
@ -926,176 +1025,6 @@ always @(posedge i_clk) begin
end
/* module 5:
* manages all that is linked with the program counter
*/
// assign goyes_off = {{12{i_imm_value[3]}}, i_imm_value, jump_off[3:0]};
// assign goyes_pc = jump_bse + goyes_off;
// // rtnyes is already handled by i_ins_test_go
// assign is_rtn_rel2 = (alu_op == `ALU_OP_JMP_REL2) && (goyes_off == 0);
// assign is_jmp_rel2 = (alu_op == `ALU_OP_JMP_REL2) && !(goyes_off == 0);
// assign jmp_carry_test = (i_test_carry && (CARRY == i_carry_val));
// assign exec_rtn_rel2 = is_rtn_rel2 && jmp_carry_test && alu_done;
// // assign set_jmp_rel2 = is_jmp_rel2 && jmp_carry_test && alu_finish;
// assign exec_jmp_rel2 = is_jmp_rel2 && jmp_carry_test && alu_done;
/* jump values generator */
reg [2:0] jump_offset_counter;
reg [19:0] jump_base;
reg [15:0] jump_offset;
reg [19:0] new_jump_offset;
reg [0:0] jump_start;
reg [0:0] jump_done;
wire [0:0] jump_relative;
assign jump_relative = op_jmp_rel_2 || op_jmp_rel_3 || op_jmp_rel_4;
always @(*) begin
new_jump_offset = 0;
jump_start = 0;
jump_done = 0;
case (jump_offset_counter)
0: begin
new_jump_offset = {{16{i_bus_nibble_in[3] && jump_relative}}, i_imm_value};
jump_start = 1;
end
1: begin
new_jump_offset = {{12{i_bus_nibble_in[3] && jump_relative}}, i_imm_value, jump_offset[ 3:0]};
if (op_jmp_rel_2) jump_done = 1;
end
2: begin
new_jump_offset = {{ 8{i_bus_nibble_in[3] && jump_relative}}, i_imm_value, jump_offset[ 7:0]};
if (op_jmp_rel_3) jump_done = 1;
end
3: begin
new_jump_offset = {{ 4{i_bus_nibble_in[3] && jump_relative}}, i_imm_value, jump_offset[11:0]};
if (op_jmp_rel_4) jump_done = 1;
end
4: begin
new_jump_offset = {i_imm_value, jump_offset[15:0]};
if (op_jmp_abs_5) jump_done = 1;
end
default: begin end
endcase
end
wire [0:0] do_set_jump_base;
wire [0:0] do_calc_jump;
wire [0:0] do_apply_jump;
assign do_set_jump_base = start_in_jmp_mode && !jump_done && jump_start;
assign do_calc_jump = mode_jmp && phase_3 && !jump_done;
assign do_apply_jump = mode_jmp && phase_3 && jump_done;
wire [19:0] jump_pc;
assign jump_pc = jump_relative?(jump_base+new_jump_offset):new_jump_offset;
/* pc update generator */
wire [19:0] next_pc;
wire [0:0] update_pc;
wire [0:0] reload_pc;
wire [0:0] pop_pc;
wire [0:0] push_pc;
wire [0:0] pc_lines_cleanup;
assign next_pc = (jump_done)?jump_pc:PC + 1;
assign update_pc = (!i_reset && just_reset) || alu_active && phase_3 && (!o_alu_stall_dec) /* || exec_unc_jmp || exec_jmp_rel2 */;
assign pop_pc = alu_active && phase_3 && i_pop && i_ins_rtn && ((!i_ins_test_go) || (i_ins_test_go && CARRY));
assign push_pc = alu_active && i_push && do_apply_jump;
assign reload_pc = (!i_reset && just_reset) || do_apply_jump || pop_pc;
assign pc_lines_cleanup = alu_active && phase_0;
always @(posedge i_clk) begin
/*
* initializes default values
*/
if (i_reset) begin
PC <= ~0;
o_bus_load_pc <= 0;
rstk_ptr <= 0;
jump_offset_counter <= 0;
jump_base <= 0;
jump_offset <= 0;
end
/*
* Similarly to the data registers,
* initializes the RSTK while the PC is first loaded
*
*/
if (alu_initializing)
RSTK[v_dest_counter_ptr] <= 0;
/**
* handles jumps
*
*/
if (do_set_jump_base) begin
// $display("ALU_PC %0d: [%d] set jump base %0d | nibble %h | rel %b | base %h | offset %h | jump_pc %h",
// phase, i_cycle_ctr, jump_offset_counter, i_imm_value, jump_relative, PC, new_jump_offset, jump_pc);
jump_base <= PC;
end
if (do_calc_jump) begin
// $display("ALU_PC %0d: [%d] calc jump %0d | nibble %h | rel %b | base %h | offset %h | jump_pc %h",
// phase, i_cycle_ctr, jump_offset_counter, i_imm_value, jump_relative, jump_base, new_jump_offset, jump_pc);
jump_offset <= new_jump_offset[15:0];
jump_offset_counter <= jump_offset_counter + 1;
end
if (do_apply_jump) begin
// $display("ALU_PC %0d: [%d] apply jump %0d | nibble %h | rel %b | base %h | offset %h | jump_pc %h",
// phase, i_cycle_ctr, jump_offset_counter, i_imm_value, jump_relative, jump_base, new_jump_offset, jump_pc);
jump_offset_counter <= 0;
end
/**
*
* Update the PC.
* Request the new PC be loaded to the other modules through
* the bus if necessary
*
*/
if (update_pc) begin
// $display("ALU_PC %0d: [%d] update pc to %h", phase, i_cycle_ctr, next_pc);
PC <= pop_pc ? RSTK[rstk_ptr - 3'b1] : next_pc;
end
if (push_pc) begin
$display("ALU_PC %0d: [%d] PUSH PC %5h to RSTK[%0d]", phase, i_cycle_ctr, (PC + 20'd1), rstk_ptr);
RSTK[rstk_ptr] <= PC + 20'd1;
rstk_ptr <= rstk_ptr + 1;
end
// $display("pop %b && rtn %b && ((!go %b) || (go %b && c %b))",
// i_pop, i_ins_rtn, !i_ins_test_go, i_ins_test_go, c_carry);
if (pop_pc) begin
$display("ALU_PC %0d: [%d] POP RSTK[%0d] to PC %5h", phase, i_cycle_ctr, rstk_ptr - 3'b1, RSTK[rstk_ptr - 3'b1]);
rstk_ptr <= rstk_ptr - 3'b1;
RSTK[rstk_ptr - 3'b1] <= 20'b0;
end
if (reload_pc) begin
$display("ALU_PC %0d: [%d] $$$$ RELOADING PC to %h $$$$",
phase, i_cycle_ctr, (pop_pc ? RSTK[rstk_ptr - 3'b1] : next_pc));
o_bus_address <= pop_pc ? RSTK[rstk_ptr - 3'b1] : next_pc;
o_bus_load_pc <= 1;
end
if (pc_lines_cleanup && o_bus_load_pc)
o_bus_load_pc <= 0;
end
/*****************************************************************************
*
* execute SETHEX and SETDEC
@ -1144,70 +1073,178 @@ end
*
****************************************************************************/
`ifndef SIM
assign i_reg_dump = 1'b0;
assign o_reg_dump = 1'b0;
`endif
`ifdef SIM
wire do_reg_dump;
wire do_alu_shpc;
assign do_reg_dump = alu_active && phase_0 && !o_bus_load_pc &&
i_ins_decoded && !o_alu_stall_dec;
i_ins_decoded && !o_alu_stall_dec && !reg_dump;
assign do_alu_shpc = alu_active && phase_0;
reg [4:0] alu_dbg_ctr;
reg [4:0] alu_dbg_src;
wire [3:0] alu_dbg_nbl;
reg [4:0] alu_dbg_ctr;
reg [0:0] reg_dump;
reg [0:0] reg_dump_done;
assign i_reg_dump = reg_dump;
assign o_en_cycle_cnt = !(do_reg_dump || reg_dump) || (do_reg_dump && !reg_dump && reg_dump_done);
assign o_reg_dump = reg_dump;
always @(posedge i_clk) begin
if (i_reset) begin
reg_dump <= 1'b0;
reg_dump_done <= 1'b0;
alu_dbg_ctr <= 5'b0;
alu_dbg_src <= 5'b0;
end
if (do_reg_dump && alu_debug_dump) begin
// $display("do_reg_dump %b | !reg_dump %b | !reg_dump_done %b", do_reg_dump, !reg_dump, !reg_dump_done);
if (do_reg_dump && alu_debug_dump && !reg_dump && !reg_dump_done) begin
reg_dump <= 1;
// display registers
$display("PC: %05h Carry: %b h: %s rp: %h RSTK7: %05h",
PC, CARRY, DEC?"DEC":"HEX", rstk_ptr, RSTK[7]);
o_pc, CARRY, DEC?"DEC":"HEX", rstk_ptr, rstk_7);
$display("P: %h HST: %b ST: %b RSTK6: %5h",
P, HST, ST, RSTK[6]);
P, HST, ST, rstk_6);
$write("A: ");
for(alu_dbg_ctr=15;alu_dbg_ctr!=31;alu_dbg_ctr=alu_dbg_ctr-1)
$write("%h", A[alu_dbg_ctr]);
$write(" R0: ");
for(alu_dbg_ctr=15;alu_dbg_ctr!=31;alu_dbg_ctr=alu_dbg_ctr-1)
$write("%h", R0[alu_dbg_ctr]);
$write(" RSTK5: %5h\n", RSTK[5]);
$write("B: ");
for(alu_dbg_ctr=15;alu_dbg_ctr!=31;alu_dbg_ctr=alu_dbg_ctr-1)
$write("%h", B[alu_dbg_ctr]);
$write(" R1: ");
for(alu_dbg_ctr=15;alu_dbg_ctr!=31;alu_dbg_ctr=alu_dbg_ctr-1)
$write("%h", R1[alu_dbg_ctr]);
$write(" RSTK4: %5h\n", RSTK[4]);
$write("C: ");
for(alu_dbg_ctr=15;alu_dbg_ctr!=31;alu_dbg_ctr=alu_dbg_ctr-1)
$write("%h", C[alu_dbg_ctr]);
$write(" R2: ");
for(alu_dbg_ctr=15;alu_dbg_ctr!=31;alu_dbg_ctr=alu_dbg_ctr-1)
$write("%h", R2[alu_dbg_ctr]);
$write(" RSTK3: %5h\n", RSTK[3]);
$write("D: ");
for(alu_dbg_ctr=15;alu_dbg_ctr!=31;alu_dbg_ctr=alu_dbg_ctr-1)
$write("%h", D[alu_dbg_ctr]);
$write(" R3: ");
for(alu_dbg_ctr=15;alu_dbg_ctr!=31;alu_dbg_ctr=alu_dbg_ctr-1)
$write("%h", R3[alu_dbg_ctr]);
$write(" RSTK2: %5h\n", RSTK[2]);
$write("D0: ");
for(alu_dbg_ctr=4;alu_dbg_ctr!=31;alu_dbg_ctr=alu_dbg_ctr-1)
$write("%h", D0[alu_dbg_ctr]);
$write(" D1: ");
for(alu_dbg_ctr=4;alu_dbg_ctr!=31;alu_dbg_ctr=alu_dbg_ctr-1)
$write("%h", D1[alu_dbg_ctr]);
$write(" R4: ");
for(alu_dbg_ctr=15;alu_dbg_ctr!=31;alu_dbg_ctr=alu_dbg_ctr-1)
$write("%h", R4[alu_dbg_ctr]);
$write(" RSTK1: %5h\n", RSTK[1]);
$display(" ADDR: %5h RSTK0: %5h",
o_bus_address, RSTK[0]);
alu_dbg_ctr = 15;
alu_dbg_src = `ALU_REG_A;
end
if (do_reg_dump && alu_debug_dump && !reg_dump && reg_dump_done) begin
// $display("ALU %0d: [%d] register dump done", phase, i_cycle_ctr);
reg_dump_done <= 1'b0;
end
if (reg_dump && (alu_dbg_src==`ALU_REG_A)) begin
$write("%h", alu_dbg_nbl);
alu_dbg_ctr <= alu_dbg_ctr - 5'b1;
if (alu_dbg_ctr == 0) begin
$write(" R0: ");
alu_dbg_src <= `ALU_REG_R0;
alu_dbg_ctr <= 15;
end
end
if (reg_dump && (alu_dbg_src==`ALU_REG_R0)) begin
$write("%h", alu_dbg_nbl);
alu_dbg_ctr <= alu_dbg_ctr - 5'b1;
if (alu_dbg_ctr == 0) begin
$write(" RSTK5: %5h\n", rstk_5);
$write("B: ");
alu_dbg_src <= `ALU_REG_B;
alu_dbg_ctr <= 15;
end
end
if (reg_dump && (alu_dbg_src==`ALU_REG_B)) begin
$write("%h", alu_dbg_nbl);
alu_dbg_ctr <= alu_dbg_ctr - 5'b1;
if (alu_dbg_ctr == 0) begin
$write(" R1: ");
alu_dbg_src <= `ALU_REG_R1;
alu_dbg_ctr <= 15;
end
end
if (reg_dump && (alu_dbg_src==`ALU_REG_R1)) begin
$write("%h", alu_dbg_nbl);
alu_dbg_ctr <= alu_dbg_ctr - 5'b1;
if (alu_dbg_ctr == 0) begin
$write(" RSTK4: %5h\n", rstk_4);
$write("C: ");
alu_dbg_src <= `ALU_REG_C;
alu_dbg_ctr <= 15;
end
end
if (reg_dump && (alu_dbg_src==`ALU_REG_C)) begin
$write("%h", alu_dbg_nbl);
alu_dbg_ctr <= alu_dbg_ctr - 5'b1;
if (alu_dbg_ctr == 0) begin
$write(" R2: ");
alu_dbg_src <= `ALU_REG_R2;
alu_dbg_ctr <= 15;
end
end
if (reg_dump && (alu_dbg_src==`ALU_REG_R2)) begin
$write("%h", alu_dbg_nbl);
alu_dbg_ctr <= alu_dbg_ctr - 5'b1;
if (alu_dbg_ctr == 0) begin
$write(" RSTK3: %5h\n", rstk_3);
$write("D: ");
alu_dbg_src <= `ALU_REG_D;
alu_dbg_ctr <= 15;
end
end
if (reg_dump && (alu_dbg_src==`ALU_REG_D)) begin
$write("%h", alu_dbg_nbl);
alu_dbg_ctr <= alu_dbg_ctr - 5'b1;
if (alu_dbg_ctr == 0) begin
$write(" R3: ");
alu_dbg_src <= `ALU_REG_R3;
alu_dbg_ctr <= 15;
end
end
if (reg_dump && (alu_dbg_src==`ALU_REG_R3)) begin
$write("%h", alu_dbg_nbl);
alu_dbg_ctr <= alu_dbg_ctr - 5'b1;
if (alu_dbg_ctr == 0) begin
$write(" RSTK2: %5h\n", rstk_2);
$write("D0: ");
alu_dbg_src <= `ALU_REG_D0;
alu_dbg_ctr <= 4;
end
end
if (reg_dump && (alu_dbg_src==`ALU_REG_D0)) begin
$write("%h", alu_dbg_nbl);
alu_dbg_ctr <= alu_dbg_ctr - 5'b1;
if (alu_dbg_ctr == 0) begin
$write(" D1: ");
alu_dbg_src <= `ALU_REG_D1;
alu_dbg_ctr <= 4;
end
end
if (reg_dump && (alu_dbg_src==`ALU_REG_D1)) begin
$write("%h", alu_dbg_nbl);
alu_dbg_ctr <= alu_dbg_ctr - 5'b1;
if (alu_dbg_ctr == 0) begin
$write(" R4: ");
alu_dbg_src <= `ALU_REG_R4;
alu_dbg_ctr <= 15;
end
end
if (reg_dump && (alu_dbg_src==`ALU_REG_R4)) begin
$write("%h", alu_dbg_nbl);
alu_dbg_ctr <= alu_dbg_ctr - 5'b1;
if (alu_dbg_ctr == 0) begin
$write(" RSTK1: %5h\n", rstk_1);
$display(" ADDR: %5h RSTK0: %5h",
o_bus_address, rstk_0);
alu_dbg_src = `ALU_REG_NOPE;
reg_dump_done <= 1'b1;
end
end
if (reg_dump && reg_dump_done && phase_3) begin
// $display("ALU %0d: [%d] end register dump", phase, i_cycle_ctr);
reg_dump <= 1'b0;
end
end
`endif

339
attic/saturn_alu_pc.v Normal file
View file

@ -0,0 +1,339 @@
/*
(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 <https://www.gnu.org/licenses/>.
*/
`ifndef _SATURN_ALU_PC
`define _SATURN_ALU_PC
`default_nettype none //
module saturn_alu_pc (
i_clk,
i_reset,
i_stalled,
i_just_reset,
i_alu_active,
i_cycle_ctr,
i_phase,
i_phase_0,
i_phase_2,
i_phase_3,
i_alu_initializing,
i_v_dest_counter_ptr,
o_bus_address,
o_bus_load_pc,
i_bus_nibble_in,
i_alu_stall_dec,
i_ins_rtn,
i_ins_test_go,
i_push,
i_pop,
i_mode_jmp,
i_carry,
i_op_jump,
i_op_jmp_rel_2,
i_op_jmp_rel_3,
i_op_jmp_rel_4,
i_op_jmp_abs_5,
o_do_apply_jump,
`ifdef SIM
o_pc,
o_rstk_ptr,
o_rstk_0,
o_rstk_1,
o_rstk_2,
o_rstk_3,
o_rstk_4,
o_rstk_5,
o_rstk_6,
o_rstk_7
`else
o_pc
`endif
);
input wire [0:0] i_clk;
input wire [0:0] i_reset;
input wire [0:0] i_stalled;
input wire [0:0] i_just_reset;
input wire [0:0] i_alu_active;
input wire [31:0] i_cycle_ctr;
input wire [1:0] i_phase;
input wire [0:0] i_phase_0;
input wire [0:0] i_phase_2;
input wire [0:0] i_phase_3;
input wire [0:0] i_alu_initializing;
input wire [2:0] i_v_dest_counter_ptr;
output reg [19:0] o_bus_address;
output reg [0:0] o_bus_load_pc;
input wire [3:0] i_bus_nibble_in;
input wire [0:0] i_alu_stall_dec;
input wire [0:0] i_ins_rtn;
input wire [0:0] i_ins_test_go;
input wire [0:0] i_push;
input wire [0:0] i_pop;
input wire [0:0] i_mode_jmp;
input wire [0:0] i_carry;
input wire [0:0] i_op_jump;
input wire [0:0] i_op_jmp_rel_2;
input wire [0:0] i_op_jmp_rel_3;
input wire [0:0] i_op_jmp_rel_4;
input wire [0:0] i_op_jmp_abs_5;
output wire [0:0] o_do_apply_jump;
output wire [19:0] o_pc;
`ifdef SIM
output wire [2:0] o_rstk_ptr;
output wire [19:0] o_rstk_0;
output wire [19:0] o_rstk_1;
output wire [19:0] o_rstk_2;
output wire [19:0] o_rstk_3;
output wire [19:0] o_rstk_4;
output wire [19:0] o_rstk_5;
output wire [19:0] o_rstk_6;
output wire [19:0] o_rstk_7;
`endif
/* module 5:
* manages all that is linked with the program counter
*/
/* main PC and RSTK registers */
reg [2:0] rstk_ptr;
reg [19:0] PC;
reg [19:0] RSTK[0:7];
assign o_pc = PC;
`ifdef SIM
assign o_rstk_ptr = rstk_ptr;
assign o_rstk_0 = RSTK[0];
assign o_rstk_1 = RSTK[1];
assign o_rstk_2 = RSTK[2];
assign o_rstk_3 = RSTK[3];
assign o_rstk_4 = RSTK[4];
assign o_rstk_5 = RSTK[5];
assign o_rstk_6 = RSTK[6];
assign o_rstk_7 = RSTK[7];
`endif
// assign goyes_off = {{12{i_imm_value[3]}}, i_imm_value, jump_off[3:0]};
// assign goyes_pc = jump_bse + goyes_off;
// // rtnyes is already handled by i_ins_test_go
// assign is_rtn_rel2 = (alu_op == `ALU_OP_JMP_REL2) && (goyes_off == 0);
// assign is_jmp_rel2 = (alu_op == `ALU_OP_JMP_REL2) && !(goyes_off == 0);
// assign jmp_carry_test = (i_test_carry && (CARRY == i_carry_val));
// assign exec_rtn_rel2 = is_rtn_rel2 && jmp_carry_test && alu_done;
// // assign set_jmp_rel2 = is_jmp_rel2 && jmp_carry_test && alu_finish;
// assign exec_jmp_rel2 = is_jmp_rel2 && jmp_carry_test && alu_done;
/* jump values generator */
reg [2:0] jump_offset_counter;
reg [19:0] jump_base;
reg [15:0] jump_offset;
reg [19:0] new_jump_offset;
reg [0:0] jump_start;
reg [0:0] jump_done;
wire [0:0] jump_relative;
assign jump_relative = i_op_jmp_rel_2 || i_op_jmp_rel_3 || i_op_jmp_rel_4;
// wire [0:0] do_set_jump_base;
wire [0:0] do_pre_calc_jump;
wire [0:0] do_calc_jump;
// assign do_set_jump_base = start_in_jmp_mode && !jump_done && jump_start;
assign do_pre_calc_jump = !i_stalled && i_op_jump && i_phase_2 && !jump_done;
assign do_calc_jump = i_mode_jmp && i_phase_3 && !jump_done;
assign o_do_apply_jump = i_mode_jmp && i_phase_3 && jump_done;
wire [19:0] jump_pc;
assign jump_pc = jump_relative?(jump_base+new_jump_offset):new_jump_offset;
/* pc update generator */
reg [19:0] pc_plus_1;
reg [2:0] rstk_ptr_plus_1;
reg [2:0] rstk_ptr_minus_1;
wire [19:0] next_pc;
wire [0:0] update_pc;
wire [0:0] reload_pc;
wire [0:0] pop_pc;
wire [0:0] push_pc;
wire [0:0] pc_lines_cleanup;
assign next_pc = (jump_done)?jump_pc:pc_plus_1;
assign update_pc = (!i_reset && i_just_reset) || i_alu_active && i_phase_3 && (!i_alu_stall_dec) /* || exec_unc_jmp || exec_jmp_rel2 */;
assign pop_pc = i_alu_active && i_phase_3 && i_pop && i_ins_rtn && ((!i_ins_test_go) || (i_ins_test_go && i_carry));
assign push_pc = i_alu_active && i_push && o_do_apply_jump;
assign reload_pc = (!i_reset && i_just_reset) || o_do_apply_jump || pop_pc;
assign pc_lines_cleanup = i_alu_active && i_phase_0;
always @(posedge i_clk) begin
/*
* initializes default values
*/
if (i_reset) begin
PC <= ~0;
o_bus_load_pc <= 0;
rstk_ptr <= 0;
jump_offset_counter <= 0;
jump_base <= 0;
jump_offset <= 0;
jump_done <= 0;
end
/* on every clock, we update
* pc + 1
* rstk_ptr - 1
* rstk_ptr + 1
*/
pc_plus_1 <= PC + 20'd1;
rstk_ptr_minus_1 <= rstk_ptr - 3'd1;
rstk_ptr_plus_1 <= rstk_ptr + 3'd1;
/*
* Similarly to the data registers,
* initializes the RSTK while the PC is first loaded
*
*/
if (i_alu_initializing)
RSTK[i_v_dest_counter_ptr] <= 0;
/**
* handles jumps
*
*/
/* nibble was read in phase 1
* in phase 2, we precalculate all values for a jump
*/
if (do_pre_calc_jump) begin
$display("ALU_PC %0d: [%d] pre_calc_jump %0d %h", i_phase, i_cycle_ctr, jump_offset_counter, i_bus_nibble_in);
case (jump_offset_counter)
0: begin
new_jump_offset <= {{16{i_bus_nibble_in[3] && jump_relative}}, i_bus_nibble_in};
jump_start <= 1'b1;
jump_base <= PC;
end
1: begin
new_jump_offset <= {{12{i_bus_nibble_in[3] && jump_relative}}, i_bus_nibble_in, jump_offset[ 3:0]};
if (i_op_jmp_rel_2) jump_done <= 1'b1;
end
2: begin
new_jump_offset <= {{ 8{i_bus_nibble_in[3] && jump_relative}}, i_bus_nibble_in, jump_offset[ 7:0]};
if (i_op_jmp_rel_3) jump_done <= 1'b1;
end
3: begin
new_jump_offset <= {{ 4{i_bus_nibble_in[3] && jump_relative}}, i_bus_nibble_in, jump_offset[11:0]};
if (i_op_jmp_rel_4) jump_done <= 1'b1;
end
4: begin
new_jump_offset <= {i_bus_nibble_in, jump_offset[15:0]};
if (i_op_jmp_abs_5) jump_done <= 1'b1;
end
default: begin end
endcase
end
/*
* in phase 3, we either update the counter
*/
if (do_calc_jump) begin
$display("ALU_PC %0d: [%d] calc jump %0d | nibble %h | rel %b | base %h | offset %h | jump_pc %h",
i_phase, i_cycle_ctr, jump_offset_counter, i_bus_nibble_in, jump_relative, jump_base, new_jump_offset, jump_pc);
jump_offset <= new_jump_offset[15:0];
jump_offset_counter <= jump_offset_counter + 3'b1;
end
/*
* or apply the jump
*/
if (o_do_apply_jump) begin
$display("ALU_PC %0d: [%d] apply jump %0d | nibble %h | rel %b | base %h | offset %h | jump_pc %h",
i_phase, i_cycle_ctr, jump_offset_counter, i_bus_nibble_in, jump_relative, jump_base, new_jump_offset, jump_pc);
jump_offset_counter <= 3'b0;
new_jump_offset <= 20'b0;
jump_start <= 1'b0;
jump_done <= 1'b0;
end
/**
*
* Update the PC.
* Request the new PC be loaded to the other modules through
* the bus if necessary
*
*/
if (update_pc) begin
// $display("ALU_PC %0d: [%d] update pc to %h", phase, i_cycle_ctr, next_pc);
PC <= pop_pc ? RSTK[rstk_ptr_minus_1] : next_pc;
end
if (push_pc) begin
$display("ALU_PC %0d: [%d] PUSH PC %5h to RSTK[%0d]", i_phase, i_cycle_ctr, pc_plus_1, rstk_ptr);
RSTK[rstk_ptr] <= pc_plus_1;
rstk_ptr <= rstk_ptr_plus_1;
end
// $display("pop %b && rtn %b && ((!go %b) || (go %b && c %b))",
// i_pop, i_ins_rtn, !i_ins_test_go, i_ins_test_go, c_carry);
if (pop_pc) begin
$display("ALU_PC %0d: [%d] POP RSTK[%0d] to PC %5h", i_phase, i_cycle_ctr, rstk_ptr_minus_1, RSTK[rstk_ptr_minus_1]);
rstk_ptr <= rstk_ptr_minus_1;
RSTK[rstk_ptr_minus_1] <= 20'b0;
end
if (reload_pc) begin
$display("ALU_PC %0d: [%d] $$$$ RELOADING PC to %h $$$$",
i_phase, i_cycle_ctr, (pop_pc ? RSTK[rstk_ptr_minus_1] : next_pc));
o_bus_address <= pop_pc ? RSTK[rstk_ptr_minus_1] : next_pc;
o_bus_load_pc <= 1'b1;
end
if (pc_lines_cleanup && o_bus_load_pc)
o_bus_load_pc <= 1'b0;
end
endmodule
`endif

View file

@ -0,0 +1,226 @@
/*
(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 <https://www.gnu.org/licenses/>.
*/
`default_nettype none //
`include "def-alu.v"
`ifndef _SATURN_ALU_REGISTERS
`define _SATURN_ALU_REGISTERS
module saturn_alu_registers (
i_clk,
i_reset,
i_stalled,
i_phase,
i_phase_3,
i_cycle_ctr,
i_alu_initializing,
i_ins_decoded,
i_src_ptr,
i_src_1,
o_src_1_nbl,
o_src_1_valid,
i_src_2,
o_src_2_nbl,
o_src_2_valid,
i_dest_ptr,
i_dest_1,
i_dest_1_nbl,
i_dest_2,
i_dest_2_nbl
`ifdef SIM
,
i_dbg_src,
i_dbg_ptr,
o_dbg_nbl
`endif
);
input wire [0:0] i_clk;
input wire [0:0] i_reset;
input wire [0:0] i_stalled;
input wire [1:0] i_phase;
input wire [0:0] i_phase_3;
input wire [31:0] i_cycle_ctr;
input wire [0:0] i_alu_initializing;
input wire [0:0] i_ins_decoded;
input wire [3:0] i_src_ptr;
input wire [4:0] i_src_1;
output reg [3:0] o_src_1_nbl;
output reg [0:0] o_src_1_valid;
input wire [4:0] i_src_2;
output reg [3:0] o_src_2_nbl;
output reg [0:0] o_src_2_valid;
input wire [3:0] i_dest_ptr;
input wire [4:0] i_dest_1;
input wire [3:0] i_dest_1_nbl;
input wire [4:0] i_dest_2;
input wire [3:0] i_dest_2_nbl;
`ifdef SIM
input wire [4:0] i_dbg_src;
input wire [3:0] i_dbg_ptr;
output reg [3:0] o_dbg_nbl;
`endif
wire [0:0] reg_store_ev;
assign reg_store_ev = !i_reset && !i_alu_initializing && !i_stalled && i_ins_decoded && i_phase_3;
/* public registers */
reg [3:0] D0[0:4];
reg [3:0] D1[0:4];
reg [3:0] A[0:15];
reg [3:0] B[0:15];
reg [3:0] C[0:15];
reg [3:0] D[0:15];
reg [3:0] R0[0:15];
reg [3:0] R1[0:15];
reg [3:0] R2[0:15];
reg [3:0] R3[0:15];
reg [3:0] R4[0:15];
`ifdef SIM
always @(i_src_ptr, i_src_1, i_src_2, i_dbg_src, i_dbg_ptr) begin
`else
always @(i_src_ptr, i_src_1, i_src_2) begin
`endif
o_src_1_nbl = 4'b0000;
o_src_1_valid = 1'b1;
o_src_2_nbl = 4'b0000;
o_src_2_valid = 1'b1;
case (i_src_1)
`ALU_REG_A: o_src_1_nbl = A [i_src_ptr];
`ALU_REG_B: o_src_1_nbl = B [i_src_ptr];
`ALU_REG_C: o_src_1_nbl = C [i_src_ptr];
`ALU_REG_D: o_src_1_nbl = D [i_src_ptr];
`ALU_REG_D0: o_src_1_nbl = D0[i_src_ptr[2:0]];
`ALU_REG_D1: o_src_1_nbl = D1[i_src_ptr[2:0]];
`ALU_REG_R0: o_src_1_nbl = R0[i_src_ptr];
`ALU_REG_R1: o_src_1_nbl = R1[i_src_ptr];
`ALU_REG_R2: o_src_1_nbl = R2[i_src_ptr];
`ALU_REG_R3: o_src_1_nbl = R3[i_src_ptr];
`ALU_REG_R4: o_src_1_nbl = R4[i_src_ptr];
default: o_src_1_valid = 1'b0;
endcase
case (i_src_2)
`ALU_REG_A: o_src_2_nbl = A [i_src_ptr];
`ALU_REG_B: o_src_2_nbl = B [i_src_ptr];
`ALU_REG_C: o_src_2_nbl = C [i_src_ptr];
`ALU_REG_D: o_src_2_nbl = D [i_src_ptr];
`ALU_REG_D0: o_src_2_nbl = D0[i_src_ptr[2:0]];
`ALU_REG_D1: o_src_2_nbl = D1[i_src_ptr[2:0]];
`ALU_REG_R0: o_src_2_nbl = R0[i_src_ptr];
`ALU_REG_R1: o_src_2_nbl = R1[i_src_ptr];
`ALU_REG_R2: o_src_2_nbl = R2[i_src_ptr];
`ALU_REG_R3: o_src_2_nbl = R3[i_src_ptr];
`ALU_REG_R4: o_src_2_nbl = R4[i_src_ptr];
default: o_src_2_valid = 1'b0;
endcase
`ifdef SIM
case (i_dbg_src)
`ALU_REG_A: o_dbg_nbl = A [i_dbg_ptr];
`ALU_REG_B: o_dbg_nbl = B [i_dbg_ptr];
`ALU_REG_C: o_dbg_nbl = C [i_dbg_ptr];
`ALU_REG_D: o_dbg_nbl = D [i_dbg_ptr];
`ALU_REG_D0: o_dbg_nbl = D0[i_dbg_ptr[2:0]];
`ALU_REG_D1: o_dbg_nbl = D1[i_dbg_ptr[2:0]];
`ALU_REG_R0: o_dbg_nbl = R0[i_dbg_ptr];
`ALU_REG_R1: o_dbg_nbl = R1[i_dbg_ptr];
`ALU_REG_R2: o_dbg_nbl = R2[i_dbg_ptr];
`ALU_REG_R3: o_dbg_nbl = R3[i_dbg_ptr];
`ALU_REG_R4: o_dbg_nbl = R4[i_dbg_ptr];
default: o_dbg_nbl = 1'bx;
endcase
`endif
end
wire [0:0] dest_1_valid;
assign dest_1_valid = (i_dest_1 == `ALU_REG_A) ||
(i_dest_1 == `ALU_REG_B) ||
(i_dest_1 == `ALU_REG_C) ||
(i_dest_1 == `ALU_REG_D) ||
(i_dest_1 == `ALU_REG_D0) ||
(i_dest_1 == `ALU_REG_D1) ||
(i_dest_1 == `ALU_REG_R0) ||
(i_dest_1 == `ALU_REG_R1) ||
(i_dest_1 == `ALU_REG_R2) ||
(i_dest_1 == `ALU_REG_R3) ||
(i_dest_1 == `ALU_REG_R4);
always @(posedge i_clk) begin
if (!i_reset && i_alu_initializing) begin
A [i_dest_ptr] <= 0;
B [i_dest_ptr] <= 0;
C [i_dest_ptr] <= 0;
D [i_dest_ptr] <= 0;
D0[i_dest_ptr[2:0]] <= 0;
D1[i_dest_ptr[2:0]] <= 0;
R0[i_dest_ptr] <= 0;
R1[i_dest_ptr] <= 0;
R2[i_dest_ptr] <= 0;
R3[i_dest_ptr] <= 0;
R4[i_dest_ptr] <= 0;
end
// $display({"REGS %0d: [%d] !i_reset %b | !i_alu_initializing %b | i_ins_decoded %b | i_phase_3 %b | store_ev %b |",
// " dest_1_valid %b | i_dest_1 %d | i_dest_ptr %h | i_dest_1_nbl %h"},
// i_phase, i_cycle_ctr,
// !i_reset, !i_alu_initializing, i_ins_decoded, i_phase_3, reg_store_ev,
// dest_1_valid, i_dest_1, i_dest_ptr, i_dest_1_nbl);
/* registers store their new value on phase 3 */
if (reg_store_ev && dest_1_valid) begin
$write("REGS %0d: [%d] ", i_phase, i_cycle_ctr);
case (i_dest_1)
`ALU_REG_A: begin
$display("A[%0d] <= %h", i_dest_ptr, i_dest_1_nbl);
A[i_dest_ptr] <= i_dest_1_nbl;
end
`ALU_REG_C: begin
$display("C[%0d] <= %h", i_dest_ptr, i_dest_1_nbl);
C[i_dest_ptr] <= i_dest_1_nbl;
end
default: begin end
endcase
end
end
endmodule
`endif

View file

@ -18,14 +18,15 @@
*/
`include "def-clocks.v"
`include "def-buscmd.v"
`ifndef _SATURN_BUS_CTRL
`define _SATURN_BUS_CTRL
`default_nettype none
`include "def-clocks.v"
`include "def-buscmd.v"
/*
* enable more debug messages
*/
@ -33,8 +34,6 @@
`define DEBUG_CTRL
`endif
module saturn_bus_ctrl (
i_clk,
i_reset,
@ -220,7 +219,7 @@ wire [0:0] cmd_PC_READ_0;
wire [0:0] cmd_PC_READ_STR;
assign cmd_PC_READ_TST = !cmd_PC_READ_F &&
(cmd_DP_WRITE_F1 || cmd_CONFIGURE_F1 || cmd_RESET_F);
(cmd_DP_WRITE_F1 || cmd_CONFIGURE_F1 || cmd_RESET_sr[3]);
assign cmd_PC_READ_0 = phase_0 && cmd_PC_READ_TST; // sets cmd_PC_READ_F
assign cmd_PC_READ_STR = cmd_PC_READ_0;
@ -372,19 +371,29 @@ assign cmd_CONFIGURE_C = phase_3 && cmd_CONFIGURE_F1 && cmd_PC_READ_F;
* RESETexecute a bus reset
*/
reg [0:0] cmd_RESET_F;
// reg [0:0] cmd_RESET_F;
wire [0:0] cmd_RESET_0;
wire [0:0] cmd_RESET_STR;
wire [0:0] cmd_RESET_ST0;
wire [0:0] cmd_RESET_US0;
wire [0:0] cmd_RESET_C;
// wire [0:0] cmd_RESET_0;
// wire [0:0] cmd_RESET_STR;
// wire [0:0] cmd_RESET_ST0;
// wire [0:0] cmd_RESET_US0;
// wire [0:0] cmd_RESET_C;
assign cmd_RESET_0 = phase_0 && i_cmd_reset && !cmd_RESET_F && !cmd_PC_READ_F; // sets cmd_RESET_F
assign cmd_RESET_STR = cmd_RESET_0;
assign cmd_RESET_ST0 = phase_3 && i_cmd_reset && !cmd_RESET_F && !cmd_PC_READ_F;
assign cmd_RESET_US0 = phase_3 && i_cmd_reset && cmd_RESET_F && cmd_PC_READ_F;
assign cmd_RESET_C = phase_0 && i_cmd_reset && cmd_RESET_F && cmd_PC_READ_F;
// assign cmd_RESET_0 = phase_0 && !i_stalled && i_cmd_reset && !cmd_RESET_F; // && !cmd_PC_READ_F; // sets cmd_RESET_F
// assign cmd_RESET_STR = cmd_RESET_0;
// assign cmd_RESET_ST0 = phase_3 && i_cmd_reset && !cmd_RESET_F && !cmd_PC_READ_F;
// assign cmd_RESET_US0 = phase_2 && i_cmd_reset && cmd_RESET_F && cmd_PC_READ_F;
// assign cmd_RESET_C = phase_0 && !i_stalled && i_cmd_reset && cmd_RESET_F && cmd_PC_READ_F;
initial cmd_RESET_sr = 9'b0;
reg [8:0] cmd_RESET_sr;
wire [0:0] cmd_RESET_busy;
wire [0:0] cmd_RESET_start;
assign cmd_RESET_busy = | cmd_RESET_sr;
assign cmd_RESET_start = !i_stalled && !bus_busy && phase_3 && i_cmd_reset;
wire [0:0] bus_busy;
assign bus_busy = cmd_RESET_busy;
// automatic stuff
@ -399,7 +408,7 @@ wire [0:0] do_read_strobe;
wire [0:0] do_write_strobe;
wire [0:0] do_strobe;
wire [0:0] do_remove_strobe;
assign do_cmd_strobe = cmd_PC_READ_STR || cmd_DP_WRITE_STR || cmd_LOAD_PC_STR || cmd_LOAD_DP_STR || cmd_CONFIGURE_STR || cmd_RESET_STR;
assign do_cmd_strobe = cmd_PC_READ_STR || cmd_DP_WRITE_STR || cmd_LOAD_PC_STR || cmd_LOAD_DP_STR || cmd_CONFIGURE_STR || cmd_RESET_sr[0];
assign do_read_strobe = do_READ_PC_STR; // || do_READ_DP_STR;
assign do_write_strobe = do_WRITE_DP_STR;
assign do_strobe = phase_0 &&
@ -417,12 +426,12 @@ assign do_unstall = o_stall_alu &&
cmd_DP_WRITE_US1 ||
do_auto_PC_READ_US0 ||
cmd_CONFIGURE_US0 ||
cmd_RESET_US0);
cmd_RESET_sr[8]);
wire [0:0] do_load_clean;
wire [0:0] do_clean;
assign do_load_clean = cmd_LOAD_PC_C || cmd_LOAD_DP_C;
assign do_clean = do_read_dp_US2 || cmd_DP_WRITE_C || cmd_CONFIGURE_C || cmd_RESET_C;
assign do_clean = do_read_dp_US2 || cmd_DP_WRITE_C || cmd_CONFIGURE_C ;
reg [0:0] addr_loop_done;
reg [0:0] init_addr_loop;
@ -452,63 +461,8 @@ initial begin
`ifdef SIM
/* debug load_pc
*/
// $monitor({"BUS - clk %b | ph %0d | osta %b | iabs %b | ",
// "LC_load_pc %b | addr_loop_done %b | do_auto_PC_READ_TST %b | cmd_LOAD_PC_F %b"},
// i_clk, phase, o_stall_alu, i_alu_busy,
// LC_load_pc, addr_loop_done, do_auto_PC_READ_TST, cmd_LOAD_PC_F);
/*
* debug auto_dp_read
*/
// $monitor({"BUS - clk %b | ph %0d | osta %b | iabs %b | ",
// "cmd_LOAD_DP_F %b | addr_loop_done %b | do_auto_DP_READ_TST %b"},
// i_clk, phase, o_stall_alu, i_alu_busy,
// cmd_LOAD_DP_F, addr_loop_done, do_auto_DP_READ_TST);
/*
* debug dp_write
*/
// $monitor({"BUS - clk %b | ph %0d | osta %b | iabs %b | ",
// "i_cmd_dp_write %b | cmd_LOAD_DP_F %b | addr_loop_done %b | do_auto_DP_READ_TST %b | cmd_DP_WRITE_F0 %b | cnd_DP_WRITE_F1 %b"},
// i_clk, phase, o_stall_alu, i_alu_busy,
// i_cmd_dp_write, cmd_LOAD_DP_F, addr_loop_done, do_auto_DP_READ_TST, cmd_DP_WRITE_F0, cmd_DP_WRITE_F1);
/*
* debug dp_read
*/
// $monitor({"BUS - clk %b | ph %0d | osta %b | iabs %b | ",
// "i_cmd_dp_read %b | cmd_LOAD_DP_F %b | addr_loop_done %b | do_auto_DP_READ_TST %b | cmd_DP_WRITE_F0 %b | cnd_DP_WRITE_F1 %b"},
// i_clk, phase, o_stall_alu, i_alu_busy,
// i_cmd_dp_read, cmd_LOAD_DP_F, addr_loop_done, do_auto_DP_READ_TST, cmd_DP_WRITE_F0, cmd_DP_WRITE_F1);
/* debug strobe for reading
*/
// $monitor({"BUS - clk %b | ph %0d | osta %b | iabs %b | ",
// "cPR %b | cLP %b | dRP %b | dRD %b | dcs %b | dral %b | drs %b | stro %b | str %b"},
// i_clk, phase, o_stall_alu, i_alu_busy,
// cmd_PC_READ_STR, cmd_LOAD_PC_STR,
// do_READ_PC_STR, do_read_dp_str,
// do_cmd_strobe, do_run_addr_loop, do_read_strobe,
// strobe_on, o_bus_strobe);
/*
* debug conditions for configure
*/
// $monitor({"BUS - clk %b | ph %0d | osta %b | iabs %b | ",
// "i_cmd_config %b | cmd_CONFIGURE_F0 %b | is_loop_finished %b | cmd_CONFIGURE_F1 %b | cmd_PC_READ_F %b"},
// i_clk, phase, o_stall_alu, i_alu_busy,
// i_cmd_config, cmd_CONFIGURE_F0, is_loop_finished, cmd_CONFIGURE_F1, cmd_PC_READ_F);
/*
* debug conditions for reset
*/
// $monitor({"BUS - clk %b | ph %0d | osta %b | iabs %b | ",
// "i_cmd_reset %b | cmd_RESET_F %b | cmd_PC_READ_F %b"},
// i_clk, phase, o_stall_alu, i_alu_busy,
// i_cmd_reset, cmd_RESET_F, cmd_PC_READ_F);
// $monitor ("BUS_CTRL %1d: [%d] i_stalled %b | i_cmd_reset %b | bus_busy %b | cmd_RESET_sr %b",
// phase, i_cycle_ctr, i_stalled, i_cmd_reset, bus_busy, cmd_RESET_sr);
`endif
end
@ -539,7 +493,7 @@ always @(posedge i_clk) begin
cmd_LOAD_DP_F <= 0;
cmd_CONFIGURE_F0 <= 0;
cmd_CONFIGURE_F1 <= 0;
cmd_RESET_F <= 0;
// cmd_RESET_F <= 0;
end
if (reset_bus) begin
@ -692,20 +646,36 @@ always @(posedge i_clk) begin
*
*****************************************************************************/
if (cmd_RESET_ST0) begin
// $display("BUS_CTRL %1d: [%d] reset stall", phase, i_cycle_ctr);
o_stall_alu <= 1;
end
// if (cmd_RESET_ST0) begin
// // $display("BUS_CTRL %1d: [%d] reset stall", phase, i_cycle_ctr);
// o_stall_alu <= 1;
// end
if (cmd_RESET_0) begin
$display("BUS_CTRL %1d: [%d] RESET", phase, i_cycle_ctr);
cmd_RESET_F <= 1;
// $display("phase_0 %b | !i_stalled %b | i_cmd_reset %b | !cmd_RESET_F %b | ! cmd_PC_READ_F %b",
// phase_0, !i_stalled, i_cmd_reset, !cmd_RESET_F, !cmd_PC_READ_F);
if (cmd_RESET_start) begin
$display("BUS_CTRL %1d: [%d] RESET start", phase, i_cycle_ctr);
cmd_RESET_sr <= 9'b1;
last_cmd <= `BUSCMD_RESET;
o_bus_data <= `BUSCMD_RESET;
o_bus_cmd_data <= 0;
o_stall_alu <= 1;
end
if (!i_stalled && cmd_RESET_busy) begin
$display("BUS_CTRL %1d: [%d] stall %b RESET_sr %b shift left", phase, i_cycle_ctr, i_stalled, cmd_RESET_sr);
cmd_RESET_sr <= {cmd_RESET_sr[7:0], 1'b0};
end
if (!i_stalled && cmd_RESET_sr[4]) begin
$display("BUS_CTRL %1d: [%d] RESET_sr %b time for PC_READ", phase, i_cycle_ctr, cmd_RESET_sr);
end
if (!i_stalled && cmd_RESET_sr[7]) begin
$display("BUS_CTRL %1d: [%d] RESET_sr %b unstall alu", phase, i_cycle_ctr, cmd_RESET_sr);
o_stall_alu <= 0;
end
/****************************************************************************
*
* Address loop handling
@ -765,7 +735,7 @@ always @(posedge i_clk) begin
cmd_DP_WRITE_F1 <= 0;
cmd_CONFIGURE_F0 <= 0;
cmd_CONFIGURE_F1 <= 0;
cmd_RESET_F <= 0;
// cmd_RESET_F <= 0;
end
/*
@ -775,7 +745,7 @@ always @(posedge i_clk) begin
*/
if (do_strobe) begin
// $display("S");
// $display("_/");
strobe_on <= 1;
end
@ -795,12 +765,12 @@ always @(posedge i_clk) begin
o_data_ptr <= o_data_ptr + 1;
end
if (do_read_stalled_by_alu) begin
if (!i_stalled && do_read_stalled_by_alu) begin
$display("BUS_CTRL %1d: [%d] read stall (alu)", phase, i_cycle_ctr);
end
if (do_remove_strobe) begin
// $display(".s");
// $display("\\_");
strobe_on <= 0;
o_bus_cmd_data <= 1;
end

View file

@ -41,14 +41,14 @@ module saturn_core (
i_clk,
i_reset,
o_halt,
o_stall,
o_bus_reset,
i_bus_data_in,
o_bus_data_out,
o_bus_strobe,
o_bus_cmd_data,
o_phase
o_bus_cmd_data
);
input wire [0:0] i_clk;
@ -61,13 +61,13 @@ module saturn_core (
btn,
led,
o_stall,
o_bus_reset,
i_bus_data_in,
o_bus_data_out,
o_bus_strobe,
o_bus_cmd_data,
o_phase
o_bus_cmd_data
);
input wire [0:0] clk_25mhz;
@ -82,9 +82,7 @@ assign i_reset = btn[1];
`endif
output wire [1:0] o_phase;
assign o_phase = clk_phase + 3;
output wire [0:0] o_stall;
output wire [0:0] o_bus_reset;
input wire [3:0] i_bus_data_in;
@ -213,11 +211,13 @@ wire [0:0] ins_unconfig;
saturn_alu m_alu (
.i_clk (i_clk),
.i_reset (i_reset),
.i_phases (clk_phases),
.i_cycle_ctr (cycle_ctr),
.i_stalled (alu_stalled),
.i_clk (i_clk),
.i_reset (i_reset),
.i_phases (clk_phases),
.i_cycle_ctr (cycle_ctr),
.i_stalled (alu_stalled),
.o_en_cycle_cnt (alu_en_cycle_cnt),
.o_reg_dump (alu_reg_dump),
.o_bus_address (alu_bus_address),
.i_bus_data_ptr (ctrl_bus_data_ptr),
@ -270,6 +270,8 @@ saturn_alu m_alu (
.o_pc (reg_pc)
);
wire [0:0] alu_en_cycle_cnt;
wire [0:0] alu_reg_dump;
// interconnections
wire [19:0] alu_bus_address;
@ -332,7 +334,7 @@ saturn_bus_ctrl m_bus_ctrl (
.o_nibble (ctrl_bus_nibble_in)
);
reg [0:0] mem_ctrl_stall;
wire [0:0] mem_ctrl_stall;
wire [0:0] bus_stalls_core;
wire [0:0] ctrl_bus_done;
wire [3:0] ctrl_bus_data_ptr;
@ -341,12 +343,10 @@ wire [3:0] ctrl_bus_nibble_in;
// `define DEBUG_CLOCKS
initial begin
clk_phases = 0;
clk_phases = 4'b0001;
clock_end = 0;
cycle_ctr = 0;
mem_ctrl_stall = 0;
clock_end = 1'b0;
cycle_ctr = 32'b0;
`ifdef DEBUG_CLOCKS
$monitor("RST %b | CLK %b | CLKP %d | CYCL %d | PC %5h | eRST %b | eDBG %b | eBSND %b | eBRECV %b | eAPR %b | eACALC %b | eINDC %b | eASAVE %b | eINDX %b",
@ -379,24 +379,26 @@ assign phase_3 = clk_phases[3];
always @(posedge i_clk) begin
clk_phases <= {clk_phases[2:0], clk_phases[3]};
if (alu_en_cycle_cnt) begin
// if (phase_1) $display("TIMING 1: [%d] increment cycle counter", cycle_ctr);
cycle_ctr <= cycle_ctr + { {31{1'b0}}, phase_0 };
cycle_ctr <= cycle_ctr + { {31{1'b0}}, phase_0 };
if (cycle_ctr == (max_cycle + 1)) begin
$display(".-----------------------------.");
$display("| OUT OF CYCLES %d |", cycle_ctr);
$display("`-----------------------------´");
clock_end <= 1;
if (cycle_ctr == (max_cycle + 1)) begin
$display(".-----------------------------.");
$display("| OUT OF CYCLES %d |", cycle_ctr);
$display("`-----------------------------´");
clock_end <= 1;
end
end
if (i_reset) begin
clk_phases <= 4'b0001;
cycle_ctr <= ~0;
clock_end <= 0;
cycle_ctr <= ~0;
max_cycle <= 125;
max_cycle <= 70;
mem_ctrl_stall <= 0;
end
end
@ -409,11 +411,14 @@ end
wire dec_stalled;
wire alu_stalled;
assign dec_stalled = alu_stalls_dec || bus_stalls_core;
assign alu_stalled = bus_stalls_core;
assign alu_stalled = bus_stalls_core || mem_ctrl_stall;
`ifdef SIM
assign o_halt = clock_end || inv_opcode;
`endif
assign mem_ctrl_stall = alu_reg_dump;
assign o_stall = alu_reg_dump;
// Verilator lint_off UNUSED
//wire [N-1:0] unused;
//assign unused = { };
@ -437,16 +442,17 @@ saturn_core saturn (
.i_clk (clk),
.i_reset (reset),
.o_halt (halt),
.o_stall (dbg_stall),
.o_bus_reset (core_bus_reset),
.i_bus_data_in (core_bus_data_in),
.o_bus_data_out (core_bus_data_out),
.o_bus_strobe (core_bus_strobe),
.o_bus_cmd_data (core_bus_cmd_data),
.o_phase (core_phase)
.o_bus_cmd_data (core_bus_cmd_data)
);
saturn_test_rom rom (
.i_stalled (dbg_stall),
.i_reset (core_bus_reset),
.i_bus_data_in (core_bus_data_out),
.o_bus_data_out (core_bus_data_in),
@ -458,14 +464,14 @@ reg [0:0] clk;
reg [0:0] reset;
wire [0:0] halt;
wire [0:0] dbg_stall;
wire [0:0] core_bus_reset;
wire [3:0] core_bus_data_in;
wire [3:0] core_bus_data_out;
wire [0:0] core_bus_strobe;
wire [0:0] core_bus_cmd_data;
wire [1:0] core_phase;
always
#10 clk = (clk === 1'b0);

View file

@ -106,6 +106,7 @@
if (do_block_80Cx) begin
o_ins_alu_op <= 1;
o_alu_op <= `ALU_OP_COPY;
o_imm_value <= i_reg_p;
next_nibble <= 0;
o_ins_decoded <= 1;
block_80Cx <= 0;

View file

@ -80,6 +80,8 @@ always @(posedge i_clk) begin
o_field <= 0;
o_field_valid <= 0;
case (i_nibble)
4'h3: // LC
o_field_start <= i_reg_p;
4'h4, 4'h5: begin // RTNC / GOC / RTNNC / GONC
$display("------------------------------------------------ 4/5xx JUMP setting fields");
o_field_start <= 0;
@ -168,7 +170,6 @@ always @(posedge i_clk) begin
end
if (do_block_3x) begin
o_field_start <= i_reg_p;
o_field_last <= (i_nibble + i_reg_p) & 4'hF;
end

View file

@ -47,24 +47,29 @@ assign reg_A_C = { 3'b000, i_nibble[2], 1'b0};
always @(posedge i_clk) begin
if (i_reset) begin
o_reg_dest <= 0;
o_reg_src1 <= 0;
o_reg_src2 <= 0;
o_reg_dest <= `ALU_REG_NOPE;
o_reg_src1 <= `ALU_REG_NOPE;
o_reg_src2 <= `ALU_REG_NOPE;
inval_opcode_regs <= 0;
end
if (do_on_first_nibble) begin
// reset values on instruction decode start
case (i_nibble)
4'h4, 4'h5, 4'h6, 4'h7: begin
o_reg_dest <= 0;
4'h3: begin
o_reg_dest <= `ALU_REG_C;
o_reg_src1 <= `ALU_REG_IMM;
o_reg_src2 <= 0;
o_reg_src2 <= `ALU_REG_NOPE;
end
4'h4, 4'h5, 4'h6, 4'h7: begin
o_reg_dest <= `ALU_REG_NOPE;
o_reg_src1 <= `ALU_REG_IMM;
o_reg_src2 <= `ALU_REG_NOPE;
end
default: begin
o_reg_dest <= 0;
o_reg_src1 <= 0;
o_reg_src2 <= 0;
o_reg_dest <= `ALU_REG_NOPE;
o_reg_src1 <= `ALU_REG_NOPE;
o_reg_src2 <= `ALU_REG_NOPE;
end
endcase
inval_opcode_regs <= 0;
@ -78,6 +83,7 @@ always @(posedge i_clk) begin
************************************************************************/
if (do_block_0x) begin
o_reg_src2 <= `ALU_REG_NOPE;
case (i_nibble)
4'h6: begin
o_reg_dest <= `ALU_REG_RSTK;
@ -87,7 +93,10 @@ always @(posedge i_clk) begin
o_reg_dest <= `ALU_REG_C;
o_reg_src1 <= `ALU_REG_RSTK;
end
4'h8: o_reg_dest <= `ALU_REG_ST;
4'h8: begin
o_reg_dest <= `ALU_REG_ST;
o_reg_src1 <= `ALU_REG_NOPE;
end
4'h9, 4'hB: begin
o_reg_dest <= `ALU_REG_C;
o_reg_src1 <= `ALU_REG_ST;
@ -113,6 +122,7 @@ always @(posedge i_clk) begin
end
if (do_block_1x) begin
o_reg_src2 <= `ALU_REG_NOPE;
case (i_nibble)
4'h6, 4'h8: begin
o_reg_dest <= `ALU_REG_D0;
@ -137,11 +147,13 @@ always @(posedge i_clk) begin
if (do_block_save_to_R_W) begin
o_reg_dest <= {2'b01, i_nibble[2:0]};
o_reg_src1 <= {3'b000, i_nibble[3]?2'b10:2'b00};
o_reg_src2 <= `ALU_REG_NOPE;
end
if (do_block_rest_from_R_W || do_block_exch_with_R_W) begin
o_reg_dest <= {3'b000, i_nibble[3]?2'b10:2'b00};
o_reg_src1 <= {2'b01, i_nibble[2:0]};
o_reg_src2 <= `ALU_REG_NOPE;
end
if (do_block_13x) begin
@ -153,32 +165,31 @@ always @(posedge i_clk) begin
if (do_block_14x_15xx) begin
o_reg_dest <= i_nibble[1]?reg_A_C:reg_DAT0DAT1;
o_reg_src1 <= i_nibble[1]?reg_DAT0DAT1:reg_A_C;
o_reg_src2 <= i_nibble[0]?`ALU_REG_D1:`ALU_REG_D0;
end
if (do_block_pointer_arith_const) begin
o_reg_dest <= `ALU_REG_NOPE;
o_reg_dest <= `ALU_REG_NOPE;
o_reg_src2 <= `ALU_REG_IMM;
end
if (do_block_2x) begin
o_reg_dest <= `ALU_REG_P;
o_reg_src1 <= `ALU_REG_IMM;
end
if (do_block_3x) begin
o_reg_dest <= `ALU_REG_C;
o_reg_src1 <= `ALU_REG_IMM;
o_reg_src2 <= `ALU_REG_NOPE;
end
if (do_block_8x) begin
o_reg_src2 <= `ALU_REG_NOPE;
case (i_nibble)
4'h4, 4'h5, 4'h6, 4'h7: begin
o_reg_dest <= `ALU_REG_ST;
o_reg_src1 <= `ALU_REG_IMM;
end
4'hC, 4'hD, 4'hE, 4'hF: begin
o_reg_dest <= 0;
o_reg_dest <= `ALU_REG_NOPE;
o_reg_src1 <= `ALU_REG_IMM;
o_reg_src2 <= 0;
end
endcase
end
@ -190,25 +201,24 @@ always @(posedge i_clk) begin
o_reg_src1 <= `ALU_REG_C;
o_reg_src2 <= `ALU_REG_NOPE;
end
4'hC: begin
o_reg_dest <= `ALU_REG_C;
o_reg_src1 <= `ALU_REG_P;
o_reg_src2 <= `ALU_REG_NOPE;
end
endcase
end
if (do_block_80Cx) begin
o_reg_dest <= `ALU_REG_C;
o_reg_src1 <= `ALU_REG_P;
o_reg_src2 <= `ALU_REG_NOPE;
end
if (do_block_81Af0x) begin
o_reg_dest <= { 2'b01, i_nibble[2:0]};
o_reg_src1 <= i_nibble[3]?`ALU_REG_C:`ALU_REG_A;
o_reg_src2 <= 0;
o_reg_src2 <= `ALU_REG_NOPE;
end
if (do_block_81Af1x) begin
o_reg_dest <= i_nibble[3]?`ALU_REG_C:`ALU_REG_A;
o_reg_src1 <= { 2'b01, i_nibble[2:0]};
o_reg_src2 <= 0;
o_reg_src2 <= `ALU_REG_NOPE;
end
if (do_block_81Af2x) begin
@ -236,21 +246,19 @@ always @(posedge i_clk) begin
end
if (do_block_Abx || do_block_Dx) begin
o_reg_src2 <= `ALU_REG_NOPE;
case ({i_nibble[3],i_nibble[2]})
2'b00: begin
o_reg_dest <= reg_ABCD;
o_reg_src1 <= `ALU_REG_ZERO;
o_reg_src2 <= 0;
end
2'b01: begin
o_reg_dest <= reg_ABCD;
o_reg_src1 <= reg_BCAC;
o_reg_src2 <= 0;
end
2'b10: begin
o_reg_dest <= reg_BCAC;
o_reg_src1 <= reg_ABCD;
o_reg_src2 <= 0;
end
2'b11: begin // exch
o_reg_dest <= reg_ABAC;
@ -270,7 +278,7 @@ always @(posedge i_clk) begin
2'b01: begin
o_reg_dest <= reg_ABCD;
o_reg_src1 <= reg_ABCD;
o_reg_src2 <= 0;
o_reg_src2 <= `ALU_REG_NOPE;
end
2'b10: begin
o_reg_dest <= reg_BCAC;
@ -288,7 +296,7 @@ always @(posedge i_clk) begin
if (do_block_Bbx) begin
o_reg_dest <= reg_ABCD;
o_reg_src1 <= reg_ABCD;
o_reg_src2 <= 0;
o_reg_src2 <= `ALU_REG_NOPE;
end
if (do_block_Cx) begin
@ -311,12 +319,13 @@ always @(posedge i_clk) begin
2'b11: begin // reg = reg - 1
o_reg_dest <= reg_ABCD;
o_reg_src1 <= reg_ABCD;
o_reg_src2 <= 0;
o_reg_src2 <= `ALU_REG_NOPE;
end
endcase
end
if (do_block_Fx) begin
o_reg_src2 <= `ALU_REG_NOPE;
case (i_nibble)
4'h8, 4'h9, 4'hA, 4'hB: begin
o_reg_dest <= reg_ABCD;

View file

@ -30,6 +30,8 @@
****************************************************************************/
module saturn_test_rom (
i_stalled,
i_reset,
i_bus_data_in,
o_bus_data_out,
@ -37,6 +39,8 @@ module saturn_test_rom (
i_bus_cmd_data
);
input wire [0:0] i_stalled;
input wire [0:0] i_reset;
input wire [3:0] i_bus_data_in;
output reg [3:0] o_bus_data_out;
@ -87,11 +91,11 @@ always @(posedge i_bus_strobe) begin
local_dp <= 0;
end
if (!i_reset)
if (!i_reset && !i_stalled)
cycles <= cycles + 1;
if (!i_bus_cmd_data) begin
if (!i_stalled && !i_bus_cmd_data ) begin
$write("ROM : [%d] COMMAND ", cycles);
case (i_bus_data_in)
@ -107,7 +111,7 @@ always @(posedge i_bus_strobe) begin
last_bus_cmd <= i_bus_data_in;
end
if (i_bus_cmd_data && s_load_pc) begin
if (!i_stalled && i_bus_cmd_data && s_load_pc) begin
$display("ROM : [%d] ADDR_IN(%0d) %h => PC [%5h]", cycles, addr_c, i_bus_data_in, local_pc);
local_pc[addr_c*4+:4] <= i_bus_data_in;
if (addr_c == 4) $display("ROM : [%d] auto PC_READ [%5h]", cycles, {i_bus_data_in, local_pc[15:0]});
@ -115,7 +119,7 @@ always @(posedge i_bus_strobe) begin
addr_c <= (addr_c == 4)?0:addr_c + 1;
end
if (i_bus_cmd_data && s_load_dp) begin
if (!i_stalled && i_bus_cmd_data && s_load_dp) begin
$display("ROM : [%d] ADDR_IN(%0d) %h => DP [%5h]", cycles, addr_c, i_bus_data_in, local_dp);
local_dp[addr_c*4+:4] <= i_bus_data_in;
if (addr_c == 4) $display("ROM : [%d] auto DP_READ [%5h]", cycles, {i_bus_data_in, local_dp[15:0]});
@ -123,19 +127,19 @@ always @(posedge i_bus_strobe) begin
addr_c <= (addr_c == 4)?0:addr_c + 1;
end
if (i_bus_cmd_data && s_pc_read) begin
if (!i_stalled && i_bus_cmd_data && s_pc_read) begin
o_bus_data_out <= rom[local_pc[`ROMBITS-1:0]];
$display("ROM : [%d] %h <= PC_READ [%5h]", cycles, rom[local_pc[`ROMBITS-1:0]], local_pc);
local_pc <= local_pc + 1;
end
if (i_bus_cmd_data && s_dp_read) begin
if (!i_stalled && i_bus_cmd_data && s_dp_read) begin
o_bus_data_out <= rom[local_dp[`ROMBITS-1:0]];
$display("ROM : [%d] %h <= DP_READ [%5h]", cycles, rom[local_dp[`ROMBITS-1:0]], local_dp);
local_dp <= local_dp + 1;
end
if (i_bus_cmd_data && s_dp_write) begin
if (!i_stalled && i_bus_cmd_data && s_dp_write) begin
$display("ROM : [%d] %h => DP_WRITE [%5h] (ignored)", cycles, i_bus_data_in, local_dp);
local_dp <= local_dp + 1;
end

View file

@ -1,124 +0,0 @@
** hp48GX-R
000000 32 96 1b 80 ad fd 01 80 e5 f4 80 f6 08 60 16 02
000000 00000 23 P= 3 | 876cc
00002 69b1 GOTO 1b9 // #001bc | 876ce goto 87888
00006 08 CLRST
00008 da A=C A
0000a df CDEX A
0000c 100 R0=A w
0000f 85e ST=1 14 // set ST.14 interrupt pending
00012 4f0 GOC 0f // #00022 | 876de goc 876ee
00015 86f ?ST=0 f // | 876e1
00018 80 GOYES 08 // #00020 | 876e4 goyes 876ec
0001a 06 RSTK=C | 876e6
0001c 6120 GOTO 021 // #0003e | 876e8 goto 8770a
000010 30 78 5f 0f 02 00 00 00 00 00 00 00 82 16 18 31
00020 03 RTNCC | 876ec RTNCC
00022 87f ?ST=1 15 | 876ee ?ST=1 15
00025 5f GOYES f5 // #0001a | GOYES 876E6
00027 02 RTNSC
00029 00
0002b 00
0002d 00
0002f 00
00031 00
00033 00
00035 00
00037 0 28 61 81
000020 17 ef 11 00 51 0d f1 1f 01 10 f5 80 f0 80 f0 14
0003e 137 CD1EX
00041 1fe1100 D1=(5) 0011e
00048 15d0 DAT1=C 1
0004c 1ff1100 D1=(5) 0011f
00053 15f0 C=DAT1 1
00057 80f0 CPEX 0
0005b 80f4 CPEX 4
000030 53 e1 db 05 08 4f 08 0f 51 75 2d 08 3c 22 54 b0
0005f 135 D1=C
00062 1ebd50 D1=(4) 05db
00068 80f4 CPEX 4
0006c 80f0 CPEX 0
00070 1557 DAT1=C W
d2 80 c3 22 45 0b
000030 53 e1 db 05 08 4f 08 0f 51 75 2d 08 3c 22 54 b0
000040 60 12 8b 0e 24 80 23 05 0b 16 f7 41 15 47 70 41
000050 15 47 51 71 71 0f 19 54 71 a2 9f 51 75 71 af bf
000060 51 75 71 1f 81 51 75 71 0f 17 54 71 14 63 41 65
000070 60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000080 e8 00 f2 6f 40 00 69 0c 88 33 00 3a 24 11 10 81
000090 33 33 33 33 96 99 99 7e 33 33 33 73 b4 eb c1 01
0000a0 58 1d fb 12 00 51 0a 08 78 80 80 ec 1b 11 eb 10
0000b0 00 51 0a 03 1c c5 80 83 0c 47 16 b2 36 04 91 09
0000c0 03 14 c5 10 89 10 e5 80 80 0a 0f 58 70 62 21 61
0000d0 1c 10 0e 00 10 34 02 43 3f 5c 8a 2a 0b 72 d8 c6
001a0 c1 01 e0 00 01 43 20 34 f3 c5 a8 a2 b0 27
0000e0 1f 70 f9 11 cb 11 00 51 0e 08 a8 b2 80 80 28 51
001bc 8d6cf10 GOVLNG 01fc6
001c3 7 f9 11 bc 11 00 15 e0 80 8a 2b 08 08 82 15
0000f0 0c 91 1a 51 0e 08 a8 b1 80 80 18 51 0c e1 e1 00
000100 51 0f b1 0f 01 10 a5 90 20 06 16 f6 f8 1d 13 70
000110 c9 73 4b 84 7e a4 50 08 c8 06 0c e7 52 a7 69 e1
000120 08 06 51 77 fa 15 f7 51 77 fa 17 f7 51 77 01 18
000130 f7 41 07 16 47 41 17 43 e1 42 06 51 37 08 81 de
000140 ed 10 5e 60 10 74 a0 c1 1f 35 17 4c 41 07 16 4c
000150 41 87 22 6f 02 0b 46 04 50 12 0a 8e d0 12 be 5d
000160 10 75 17 ef 11 00 51 0f 31 05 87 e4 f0 02 b1 0e
000170 01 80 82 2d 2b c6 5e fd 03 1c c5 80 83 00 65 8e
000180 0d 25 70 91 2e 41 0e 26 d0 82 06 06 13 10 41 8c
000190 3e ad 80 80 1f c9 d1 12 c5 10 e9 30 80 51 0c 2d
0001a0 91 09 51 0c d8 b7 43 10 99 30 40 51 0c 91 2e 41
0001b0 0e 36 01 11 c4 91 38 51 0a 03 ba a0 51 0e 09 96
0001c0 0f 17 e9 12 c4 f8 a5 1b 80 af 9d 01 91 08 51 0e
0001d0 08 b8 90 19 e9 30 c0 51 0c 70 91 2e 41 0c 03 00
0001e0 02 b1 10 01 10 a5 80 80 36 00 08 48 12 85 80 80
0001f0 34 09 08 10 19 11 25 82 80 b4 29 08 80 80 1f c9
000200 10 e5 10 4e 65 10 d5 80 80 19 51 0c f8 1b 01 47
000210 7f 91 0d 0d 51 0a 08 48 d3 c6 c4 3a 74 48 00 2c
000220 31 14 25 13 8b 13 00 51 36 3b 12 89 13 25 93 23
000230 0f f8 1b 01 47 35 85 1e 4e 65 10 f5 10 c9 10 c5
000240 80 80 00 c2 12 bc 60 09 5e b0 04 2f 60 02 17 80
000250 80 86 0b 91 14 41 da 18 9e 51 10 f5 86 80 a6 12
000260 91 13 51 08 08 98 58 69 52 8a aa 40 02 c5 a5 7f
000270 08 28 31 81 4f 13 70 fa 9b 06 27 08 28 11 81 4f
000280 13 70 fa 9b 46 2d 52 8a 3a b0 e0 20 e5 20 a5 a8
000290 03 04 0e 1a ee 51 10 55 20 60 e4 9e e2 10 6b 56
0002a0 0a 6a 8e 80 b9 e1 19 05 51 6d 29 5e d2 fa f4 f4
0002b0 a4 a6 6a cc 14 9e 31 10 73 2c 31 d7 14 94 e1 19
0002c0 05 51 33 13 df e9 7e 90 82 53 e1 1e 05 51 0b 03
0002d0 03 0e 36 20 09 a6 13 29 11 a5 80 80 07 1b 08 28
000fd0 61 84 80 cc fa 01 07 b2 e8 49 fc d8 43 51 80 65
000fe0 86 00 f2 48 86 24 58 67 13 80 75 66 00 48 87 25
01fc0 68 00 2f
01fc6 846 ST=0 6
01fc9 842 ST=0 2
01fcc 857 ST=1 7
01fcf 6310 GOTO 013 => 01fe3
8 57 66 00 84 78 52
000ff0 58 86 c0 8f f4 08 8a cd 18 70 78 c6 83 d0 8f 39
01fe0 856
01fe3 80cf C=P f
8 4f 80 a8 dc 81 07 87 6c 38 0d f8 93
001000 07 88 18 12 9b 10 00 51 0e 08 b8 90 80 80 1a 08

View file

@ -1,46 +0,0 @@
first delay is <async> -> posedge $glbnet$clk
second delay is posedge $glbnet$clk -> <async>
cells speed 1 delay (a) 1 delay 1 arcs speed 2 delay (a) 2 delay 2
2019-02-12 07:37 29 490.92MHz 2.68ns 330.14MHz 1.99ns
2019-02-12 07:48 29 490.92MHz 14.34ns 2.20ns 350.39MHz 4.14ns 1.77ns
2019-02-12 08:22 29 490.92MHz 14.34ns 2.68ns 330.58MHz 4.71ns 1.84ns
2019-02-12 08:39 29 490.92MHz 14.10ns 3.16ns 96 335.35MHz 4.46ns 1.93ns
2019-02-12 08:48 29 490.92MHz 14.10ns 3.16ns 96 335.35MHz 4.46ns 1.93ns
2019-02-12 11:11 29 490.92MHz 14.58ns 2.44ns 96 330.03MHz 4.74ns 2.04ns
2019-02-12 12:15 29 468.38MHz 14.34ns 2.68ns 96 330.58MHz 4.74ns 1.97ns
2019-02-12 12:48 48 242.95MHz 13.38ns 2.92ns 240 162.44MHz 4.13ns 2.05ns
2019-02-12 13:25 48 165.54MHz 14.58ns 3.64ns 240 176.46MHz 4.75ns 2.06ns
2019-02-12 13:28 48 142.84MHz 14.34ns 3.40ns 240 168.21MHz 4.71ns 2.31ns
2019-02-12 13:38 55 196.93MHz 14.58ns 3.16ns 343 166.53MHz 4.43ns 2.06ns
2019-02-12 14:51 50 84.74MHz 13.38ns 3.88ns 271 170.13MHz 4.15ns 2.35ns
2019-02-12 15:10 50 84.74MHz 13.38ns 3.88ns 271 170.13MHz 4.15ns 2.35ns
2019-02-12 15:39 50 75.52MHz 12.90ns 5.09ns 271 166.53MHz 4.14ns 2.55ns
2019-02-12 16:04 48 112.10MHz 14.34ns 2.92ns 241 163.99MHz 4.72ns 2.00ns
2019-02-12 17:27 56 142.90MHz 14.34ns 3.40ns 345 160.03MHz 4.95ns 2.25ns
2019-02-12 18:00 51 213.36MHz 13.98ns 2.92ns 273 165.43MHz 4.78ns 2.05ns
2019-02-12 22:07 49 112.10MHz 14.58ns 3.16ns 241 168.95MHz 4.74ns 1.93ns
2019-02-12 22:12 51 138.10MHz 15.06ns 2.92ns 273 154.61MHz 4.78ns 2.00ns
2019-02-12 22:20 49 112.10MHz 14.34ns 3.64ns 241 171.50MHz 4.55ns 2.33ns
2019-02-12 23:27 55 202.72MHz 13.14ns 4.61ns 344 162.63MHz 4.88ns 2.21ns
2019-02-13 07:46 48 98.83MHz 13.86ns 2.92ns 241 169.41MHz 4.11ns 1.92ns
2019-02-13 14:53 51 153.35MHz 16.74ns 3.40ns 273 155.47MHz 5.53ns 2.09ns
2019-02-13 23:21 318 113.77MHz 25.44ns 13.97ns 3061 117.75MHz 9.56ns 4.08ns
2019-02-14 09:00 353 118.23MHz 26.00ns 12.28ns 3334 119.40MHz 10.08ns 3.84ns
2019-02-14 22:11 403 115.09MHz 27.38ns 11.32ns 2430 111.51MHz 12.62ns 3.57ns
2019-02-15 07:14 535 97.16MHz 26.57ns 9.16ns 3073 96.10MHz 13.38ns 3.13ns
2019-02-15 11:07 577 102.13MHz 28.63ns 11.09ns 3270 101.77MHz 13.65ns 3.67ns
2019-02-15 17:12 1544 70.76MHz 33.39ns 12.77ns 10374 75.73MHz 16.74ns 3.99ns
2019-02-16 11:18 1552 72.00MHz 34.10ns 10.85ns 10072 75.65MHz 17.35ns 3.46ns
2019-02-16 12:18 1453 62.31MHz 33.86ns 12.05ns 10323 70.66MHz 16.96ns 3.59ns
2019-02-16 22:54 1629 60.66MHz 33.62ns 12.05ns 11562 56.91MHz 17.11ns 3.84ns
2019-02-17 12:58 1679 68.43MHz 38.91ns 12.77ns 10906 70.19MHz 18.76ns 4.00ns
2019-02-17 15:11 1677 70.29MHz 34.92ns 13.01ns 11788 74.69MHz 17.42ns 3.88ns
2019-02-17 19:30 1637 74.68MHz 34.80ns 12.77ns 11687 68.49Mhz 18.03ns 4.01ns
2019-02-17 20:25 1733 72.37MHz 32.87ns 12.77ns 12213 73.52MHz 16.22ns 3.87ns
2019-02-17 21:21 1734 71.16MHz 32.10ns 12.05ns 11359 73.56MHz 17.19ns 3.73ns
2019-02-17 22:31 1573 77.32MHz 32.91ns 12.77ns 10265 70.53MHz 17.35ns 4.13ns
2019-02-17 22:48 1067 69.94MHz 32.87ns 12.77ns 6427 74.33MHz 17.71ns 3.96ns
2019-02-17 23:04 1158 64.11MHz 37.87ns 12.77ns 7149 66.74MHz 19.03ns 4.06ns
2019-02-18 07:45 1128 74.65MHz 36.49ns 13.73ns 7586 75.72MHz 17.57ns 3.99ns
2019-02-19 16:26 1500 64.68MHz 42.16ns 17.32ns 10387 63.05MHz 19.43ns 7.69ns

View file

@ -1,73 +0,0 @@
$date
Thu Jan 31 14:59:26 2019
$end
$version
Icarus Verilog
$end
$timescale
1s
$end
$scope module mask_gen_tb $end
$var reg 4 ! nw [3:0] $end
$upscope $end
$scope module mask_gen_tb $end
$var reg 4 " ns [3:0] $end
$upscope $end
$scope module mask_gen_tb $end
$var wire 64 # m [63:0] $end
$upscope $end
$enddefinitions $end
#0
$dumpvars
bx #
bx "
bx !
$end
#10
b0 "
b100 !
#30
b111111111111111111110000 #
b1 "
#50
b1111111111111111111100000000 #
b10 "
#70
b11111111111111111111000000000000 #
b11 "
#90
b111111111111111111110000000000000000 #
b100 "
#110
b1111111111111111111100000000000000000000 #
b101 "
#130
b11111111111111111111000000000000000000000000 #
b110 "
#150
b111111111111111111110000000000000000000000000000 #
b111 "
#170
b1111111111111111111100000000000000000000000000000000 #
b1000 "
#190
b11111111111111111111000000000000000000000000000000000000 #
b1001 "
#210
b111111111111111111110000000000000000000000000000000000000000 #
b1010 "
#230
b1111111111111111111100000000000000000000000000000000000000000000 #
b1011 "
#250
b1111111111111111000000000000000000000000000000000000000000001111 #
b1100 "
#270
b1111111111110000000000000000000000000000000000000000000011111111 #
b1101 "
#290
b1111111100000000000000000000000000000000000000000000111111111111 #
b1110 "
#310
b1111000000000000000000000000000000000000000000001111111111111111 #
b1111 "