mirror of
https://github.com/sxpert/hp-saturn
synced 2024-12-27 09:58:16 +01:00
implement CLRHST and variants
implement SET[HEX|DEC]
This commit is contained in:
parent
735504d2b3
commit
908b96df6f
6 changed files with 112 additions and 16 deletions
|
@ -147,7 +147,7 @@ always @(posedge i_clk) begin
|
||||||
end
|
end
|
||||||
|
|
||||||
`ifdef SIM
|
`ifdef SIM
|
||||||
if (cycle_ctr == 65) begin
|
if (cycle_ctr == 85) begin
|
||||||
bus_halt <= 1'b1;
|
bus_halt <= 1'b1;
|
||||||
$display("BUS %0d: [%d] enough cycles for now", phase, cycle_ctr);
|
$display("BUS %0d: [%d] enough cycles for now", phase, cycle_ctr);
|
||||||
end
|
end
|
||||||
|
|
|
@ -79,6 +79,7 @@ saturn_control_unit control_unit (
|
||||||
|
|
||||||
/* debugger interface */
|
/* debugger interface */
|
||||||
.o_current_pc (ctrl_current_pc),
|
.o_current_pc (ctrl_current_pc),
|
||||||
|
.o_reg_alu_mode (ctrl_reg_alu_mode),
|
||||||
.o_reg_hst (ctrl_reg_hst),
|
.o_reg_hst (ctrl_reg_hst),
|
||||||
.o_reg_st (ctrl_reg_st),
|
.o_reg_st (ctrl_reg_st),
|
||||||
.o_reg_p (ctrl_reg_p),
|
.o_reg_p (ctrl_reg_p),
|
||||||
|
@ -104,6 +105,7 @@ wire [0:0] ctrl_unit_no_read;
|
||||||
|
|
||||||
/* debugger insterface */
|
/* debugger insterface */
|
||||||
wire [19:0] ctrl_current_pc;
|
wire [19:0] ctrl_current_pc;
|
||||||
|
wire [0:0] ctrl_reg_alu_mode;
|
||||||
wire [3:0] ctrl_reg_hst;
|
wire [3:0] ctrl_reg_hst;
|
||||||
wire [15:0] ctrl_reg_st;
|
wire [15:0] ctrl_reg_st;
|
||||||
wire [3:0] ctrl_reg_p;
|
wire [3:0] ctrl_reg_p;
|
||||||
|
@ -137,6 +139,7 @@ saturn_debugger debugger (
|
||||||
|
|
||||||
/* debugger interface */
|
/* debugger interface */
|
||||||
.i_current_pc (ctrl_current_pc),
|
.i_current_pc (ctrl_current_pc),
|
||||||
|
.i_reg_alu_mode (ctrl_reg_alu_mode),
|
||||||
.i_reg_hst (ctrl_reg_hst),
|
.i_reg_hst (ctrl_reg_hst),
|
||||||
.i_reg_st (ctrl_reg_st),
|
.i_reg_st (ctrl_reg_st),
|
||||||
.i_reg_p (ctrl_reg_p),
|
.i_reg_p (ctrl_reg_p),
|
||||||
|
|
|
@ -45,6 +45,7 @@ module saturn_control_unit (
|
||||||
/* debugger interface */
|
/* debugger interface */
|
||||||
|
|
||||||
o_current_pc,
|
o_current_pc,
|
||||||
|
o_reg_alu_mode,
|
||||||
o_reg_p,
|
o_reg_p,
|
||||||
o_reg_hst,
|
o_reg_hst,
|
||||||
o_reg_st,
|
o_reg_st,
|
||||||
|
@ -85,6 +86,8 @@ assign o_error = control_unit_error || dec_error;
|
||||||
/* debugger interface */
|
/* debugger interface */
|
||||||
|
|
||||||
output wire [19:0] o_current_pc;
|
output wire [19:0] o_current_pc;
|
||||||
|
output wire [0:0] o_reg_alu_mode;
|
||||||
|
assign o_reg_alu_mode = reg_alu_mode;
|
||||||
output wire [3:0] o_reg_p;
|
output wire [3:0] o_reg_p;
|
||||||
output wire [3:0] o_reg_hst;
|
output wire [3:0] o_reg_hst;
|
||||||
output wire [15:0] o_reg_st;
|
output wire [15:0] o_reg_st;
|
||||||
|
@ -176,17 +179,20 @@ wire [0:0] dec_error;
|
||||||
wire [0:0] inst_alu = (dec_instr_type == `INSTR_TYPE_ALU);
|
wire [0:0] inst_alu = (dec_instr_type == `INSTR_TYPE_ALU);
|
||||||
wire [0:0] inst_jump = (dec_instr_type == `INSTR_TYPE_JUMP);
|
wire [0:0] inst_jump = (dec_instr_type == `INSTR_TYPE_JUMP);
|
||||||
|
|
||||||
wire [0:0] reg_dest_c = (dec_alu_reg_dest == `ALU_REG_C);
|
wire [0:0] reg_dest_c = (dec_alu_reg_dest == `ALU_REG_C);
|
||||||
wire [0:0] reg_dest_st = (dec_alu_reg_dest == `ALU_REG_ST);
|
wire [0:0] reg_dest_hst = (dec_alu_reg_dest == `ALU_REG_HST);
|
||||||
wire [0:0] reg_dest_p = (dec_alu_reg_dest == `ALU_REG_P);
|
wire [0:0] reg_dest_st = (dec_alu_reg_dest == `ALU_REG_ST);
|
||||||
|
wire [0:0] reg_dest_p = (dec_alu_reg_dest == `ALU_REG_P);
|
||||||
|
|
||||||
wire [0:0] reg_src_1_p = (dec_alu_reg_src_1 == `ALU_REG_P);
|
wire [0:0] reg_src_1_p = (dec_alu_reg_src_1 == `ALU_REG_P);
|
||||||
wire [0:0] reg_src_1_imm = (dec_alu_reg_src_1 == `ALU_REG_IMM);
|
wire [0:0] reg_src_1_imm = (dec_alu_reg_src_1 == `ALU_REG_IMM);
|
||||||
|
|
||||||
wire [0:0] aluop_copy = inst_alu && (dec_alu_opcode == `ALU_OP_COPY);
|
wire [0:0] aluop_copy = inst_alu && (dec_alu_opcode == `ALU_OP_COPY);
|
||||||
|
wire [0:0] aluop_clr_mask = inst_alu && (dec_alu_opcode == `ALU_OP_CLR_MASK);
|
||||||
|
|
||||||
wire [0:0] inst_alu_p_eq_n = aluop_copy && reg_dest_p && reg_src_1_imm;
|
wire [0:0] inst_alu_p_eq_n = aluop_copy && reg_dest_p && reg_src_1_imm;
|
||||||
wire [0:0] inst_alu_c_eq_p_n = aluop_copy && reg_dest_c && reg_src_1_p;
|
wire [0:0] inst_alu_c_eq_p_n = aluop_copy && reg_dest_c && reg_src_1_p;
|
||||||
|
wire [0:0] inst_alu_clrhst_n = aluop_clr_mask && reg_dest_hst && reg_src_1_imm;
|
||||||
wire [0:0] inst_alu_st_eq_01_n = aluop_copy && reg_dest_st && reg_src_1_imm;
|
wire [0:0] inst_alu_st_eq_01_n = aluop_copy && reg_dest_st && reg_src_1_imm;
|
||||||
|
|
||||||
wire [0:0] inst_alu_other = !(inst_alu_p_eq_n ||
|
wire [0:0] inst_alu_other = !(inst_alu_p_eq_n ||
|
||||||
|
@ -230,14 +236,18 @@ saturn_regs_pc_rstk regs_pc_rstk (
|
||||||
*
|
*
|
||||||
*************************************************************************************************/
|
*************************************************************************************************/
|
||||||
|
|
||||||
|
reg [0:0] reg_alu_mode;
|
||||||
|
|
||||||
reg [3:0] reg_C[0:15];
|
reg [3:0] reg_C[0:15];
|
||||||
reg [3:0] reg_HST;
|
reg [3:0] reg_HST;
|
||||||
reg [15:0] reg_ST;
|
reg [15:0] reg_ST;
|
||||||
reg [3:0] reg_P;
|
reg [3:0] reg_P;
|
||||||
wire [19:0] reg_PC;
|
wire [19:0] reg_PC;
|
||||||
|
|
||||||
|
|
||||||
wire [0:0] reload_PC;
|
wire [0:0] reload_PC;
|
||||||
|
|
||||||
always @(*) begin
|
always @(i_dbg_register, i_dbg_reg_ptr) begin
|
||||||
case (i_dbg_register)
|
case (i_dbg_register)
|
||||||
`ALU_REG_C: o_dbg_reg_nibble <= reg_C[i_dbg_reg_ptr];
|
`ALU_REG_C: o_dbg_reg_nibble <= reg_C[i_dbg_reg_ptr];
|
||||||
default: o_dbg_reg_nibble <= 4'h0;
|
default: o_dbg_reg_nibble <= 4'h0;
|
||||||
|
@ -277,6 +287,7 @@ initial begin
|
||||||
load_pc_loop = 1'b0;
|
load_pc_loop = 1'b0;
|
||||||
|
|
||||||
/* registers */
|
/* registers */
|
||||||
|
reg_alu_mode = 1'b0;
|
||||||
reg_HST = 4'b0;
|
reg_HST = 4'b0;
|
||||||
reg_ST = 16'b0;
|
reg_ST = 16'b0;
|
||||||
reg_P = 4'b0;
|
reg_P = 4'b0;
|
||||||
|
@ -383,6 +394,20 @@ always @(posedge i_clk) begin
|
||||||
reg_C[dec_alu_ptr_begin] <= reg_P;
|
reg_C[dec_alu_ptr_begin] <= reg_P;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if (inst_alu_clrhst_n) begin
|
||||||
|
`ifdef SIM
|
||||||
|
$write("CTRL %0d: [%d] exec : ", i_phase, i_cycle_ctr);
|
||||||
|
case (dec_alu_imm_value)
|
||||||
|
4'h1: $display("XM=0");
|
||||||
|
4'h2: $display("SB=0");
|
||||||
|
4'h4: $display("SR=0");
|
||||||
|
4'h8: $display("MP=0");
|
||||||
|
4'hF: $display("CLRHST");
|
||||||
|
default: $display("CLRHST %h", dec_alu_imm_value);
|
||||||
|
endcase
|
||||||
|
`endif
|
||||||
|
reg_HST = reg_HST & ~dec_alu_imm_value;
|
||||||
|
end
|
||||||
|
|
||||||
/* 8[45]n ST=[01] n */
|
/* 8[45]n ST=[01] n */
|
||||||
if (inst_alu_st_eq_01_n) begin
|
if (inst_alu_st_eq_01_n) begin
|
||||||
|
@ -394,6 +419,18 @@ always @(posedge i_clk) begin
|
||||||
* the general case
|
* the general case
|
||||||
*/
|
*/
|
||||||
end
|
end
|
||||||
|
`INSTR_TYPE_SET_MODE :
|
||||||
|
begin
|
||||||
|
`ifdef SIM
|
||||||
|
$write("CTRL %0d: [%d] exec : ", i_phase, i_cycle_ctr);
|
||||||
|
case (dec_alu_imm_value)
|
||||||
|
4'h0: $display("SETHEX");
|
||||||
|
4'h1: $display("SETDEC");
|
||||||
|
default: begin end /* does not exist */
|
||||||
|
endcase
|
||||||
|
`endif
|
||||||
|
reg_alu_mode <= dec_alu_imm_value[0];
|
||||||
|
end
|
||||||
`INSTR_TYPE_JUMP: begin end
|
`INSTR_TYPE_JUMP: begin end
|
||||||
`INSTR_TYPE_RESET:
|
`INSTR_TYPE_RESET:
|
||||||
begin
|
begin
|
||||||
|
@ -430,6 +467,7 @@ always @(posedge i_clk) begin
|
||||||
load_pc_loop <= 1'b0;
|
load_pc_loop <= 1'b0;
|
||||||
|
|
||||||
/* registers */
|
/* registers */
|
||||||
|
reg_alu_mode <= 1'b0;
|
||||||
reg_HST <= 4'b0;
|
reg_HST <= 4'b0;
|
||||||
reg_ST <= 16'b0;
|
reg_ST <= 16'b0;
|
||||||
reg_P <= 4'b0;
|
reg_P <= 4'b0;
|
||||||
|
|
|
@ -35,6 +35,7 @@ module saturn_debugger (
|
||||||
|
|
||||||
/* interface from the control unit */
|
/* interface from the control unit */
|
||||||
i_current_pc,
|
i_current_pc,
|
||||||
|
i_reg_alu_mode,
|
||||||
i_reg_hst,
|
i_reg_hst,
|
||||||
i_reg_st,
|
i_reg_st,
|
||||||
i_reg_p,
|
i_reg_p,
|
||||||
|
@ -67,6 +68,7 @@ output reg [0:0] o_debug_cycle;
|
||||||
|
|
||||||
/* inteface from the control unit */
|
/* inteface from the control unit */
|
||||||
input wire [19:0] i_current_pc;
|
input wire [19:0] i_current_pc;
|
||||||
|
input wire [0:0] i_reg_alu_mode;
|
||||||
input wire [3:0] i_reg_hst;
|
input wire [3:0] i_reg_hst;
|
||||||
input wire [15:0] i_reg_st;
|
input wire [15:0] i_reg_st;
|
||||||
input wire [3:0] i_reg_p;
|
input wire [3:0] i_reg_p;
|
||||||
|
@ -227,9 +229,9 @@ always @(posedge i_clk) begin
|
||||||
5'd0: registers_str[registers_ctr] <= "h";
|
5'd0: registers_str[registers_ctr] <= "h";
|
||||||
5'd1: registers_str[registers_ctr] <= ":";
|
5'd1: registers_str[registers_ctr] <= ":";
|
||||||
5'd2: registers_str[registers_ctr] <= " ";
|
5'd2: registers_str[registers_ctr] <= " ";
|
||||||
5'd3: registers_str[registers_ctr] <= "@";
|
5'd3: registers_str[registers_ctr] <= i_reg_alu_mode?"D":"H";
|
||||||
5'd4: registers_str[registers_ctr] <= "E";
|
5'd4: registers_str[registers_ctr] <= "E";
|
||||||
5'd5: registers_str[registers_ctr] <= "@";
|
5'd5: registers_str[registers_ctr] <= i_reg_alu_mode?"C":"X";
|
||||||
5'd6: registers_str[registers_ctr] <= " ";
|
5'd6: registers_str[registers_ctr] <= " ";
|
||||||
endcase
|
endcase
|
||||||
registers_reg_ptr <= registers_reg_ptr + 5'd1;
|
registers_reg_ptr <= registers_reg_ptr + 5'd1;
|
||||||
|
|
|
@ -97,11 +97,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
`define INSTR_TYPE_NOP 0
|
`define INSTR_TYPE_NOP 0
|
||||||
`define INSTR_TYPE_ALU 1
|
`define INSTR_TYPE_ALU 1
|
||||||
`define INSTR_TYPE_JUMP 2
|
`define INSTR_TYPE_SET_MODE 2
|
||||||
`define INSTR_TYPE_RESET 3
|
`define INSTR_TYPE_JUMP 3
|
||||||
|
`define INSTR_TYPE_RESET 4
|
||||||
|
|
||||||
`define INSTR_TYPE_NONE 15
|
`define INSTR_TYPE_NONE 15
|
||||||
|
|
||||||
`endif
|
`endif
|
|
@ -121,11 +121,13 @@ reg [0:0] decode_started;
|
||||||
* decoder block variables
|
* decoder block variables
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
reg [0:0] block_0x;
|
||||||
reg [0:0] block_2x;
|
reg [0:0] block_2x;
|
||||||
reg [0:0] block_6x;
|
reg [0:0] block_6x;
|
||||||
reg [0:0] block_8x;
|
reg [0:0] block_8x;
|
||||||
reg [0:0] block_80x;
|
reg [0:0] block_80x;
|
||||||
reg [0:0] block_80Cx;
|
reg [0:0] block_80Cx;
|
||||||
|
reg [0:0] block_82x;
|
||||||
reg [0:0] block_84x_85x;
|
reg [0:0] block_84x_85x;
|
||||||
|
|
||||||
reg [0:0] block_JUMP;
|
reg [0:0] block_JUMP;
|
||||||
|
@ -159,11 +161,13 @@ initial begin
|
||||||
just_reset = 1'b1;
|
just_reset = 1'b1;
|
||||||
decode_started = 1'b0;
|
decode_started = 1'b0;
|
||||||
|
|
||||||
|
block_0x = 1'b0;
|
||||||
block_2x = 1'b0;
|
block_2x = 1'b0;
|
||||||
block_6x = 1'b0;
|
block_6x = 1'b0;
|
||||||
block_8x = 1'b0;
|
block_8x = 1'b0;
|
||||||
block_80x = 1'b0;
|
block_80x = 1'b0;
|
||||||
block_80Cx = 1'b0;
|
block_80Cx = 1'b0;
|
||||||
|
block_82x = 1'b0;
|
||||||
block_84x_85x = 1'b0;
|
block_84x_85x = 1'b0;
|
||||||
|
|
||||||
block_JUMP = 1'b0;
|
block_JUMP = 1'b0;
|
||||||
|
@ -208,6 +212,7 @@ always @(posedge i_clk) begin
|
||||||
|
|
||||||
decode_started <= 1'b1;
|
decode_started <= 1'b1;
|
||||||
case (i_nibble)
|
case (i_nibble)
|
||||||
|
4'h0: block_0x <= 1'b1;
|
||||||
4'h2: block_2x <= 1'b1;
|
4'h2: block_2x <= 1'b1;
|
||||||
4'h6:
|
4'h6:
|
||||||
begin
|
begin
|
||||||
|
@ -229,6 +234,25 @@ always @(posedge i_clk) begin
|
||||||
if (i_phases[2] && decode_started) begin
|
if (i_phases[2] && decode_started) begin
|
||||||
$display("DECODER %0d: [%d] nb= %h - decoding", i_phase, i_cycle_ctr, i_nibble);
|
$display("DECODER %0d: [%d] nb= %h - decoding", i_phase, i_cycle_ctr, i_nibble);
|
||||||
|
|
||||||
|
if (block_0x) begin
|
||||||
|
case (i_nibble)
|
||||||
|
4'h4, 4'h5:
|
||||||
|
begin
|
||||||
|
o_instr_type <= `INSTR_TYPE_SET_MODE;
|
||||||
|
o_alu_imm_value <= {3'b000, i_nibble[0]};
|
||||||
|
o_instr_decoded <= 1'b1;
|
||||||
|
o_instr_execute <= 1'b1;
|
||||||
|
decode_started <= 1'b0;
|
||||||
|
end
|
||||||
|
default:
|
||||||
|
begin
|
||||||
|
$display("DECODER %0d: [%d] block_0x %h", i_phase, i_cycle_ctr, i_nibble);
|
||||||
|
o_decoder_error <= 1'b1;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
block_0x <= 1'b0;
|
||||||
|
end
|
||||||
|
|
||||||
if (block_2x) begin
|
if (block_2x) begin
|
||||||
o_alu_reg_dest <= `ALU_REG_P;
|
o_alu_reg_dest <= `ALU_REG_P;
|
||||||
o_alu_reg_src_1 <= `ALU_REG_IMM;
|
o_alu_reg_src_1 <= `ALU_REG_IMM;
|
||||||
|
@ -255,6 +279,7 @@ always @(posedge i_clk) begin
|
||||||
if (block_8x) begin
|
if (block_8x) begin
|
||||||
case (i_nibble)
|
case (i_nibble)
|
||||||
4'h0: block_80x <= 1'b1;
|
4'h0: block_80x <= 1'b1;
|
||||||
|
4'h2: block_82x <= 1'b1;
|
||||||
4'h4, 4'h5:
|
4'h4, 4'h5:
|
||||||
begin
|
begin
|
||||||
o_alu_reg_dest <= `ALU_REG_ST;
|
o_alu_reg_dest <= `ALU_REG_ST;
|
||||||
|
@ -265,9 +290,10 @@ always @(posedge i_clk) begin
|
||||||
o_instr_type <= `INSTR_TYPE_ALU;
|
o_instr_type <= `INSTR_TYPE_ALU;
|
||||||
block_84x_85x <= 1'b1;
|
block_84x_85x <= 1'b1;
|
||||||
end
|
end
|
||||||
4'hD:
|
4'hD, 4'hF:
|
||||||
begin
|
begin
|
||||||
o_instr_type <= `INSTR_TYPE_JUMP;
|
o_instr_type <= `INSTR_TYPE_JUMP;
|
||||||
|
o_push_pc <= 1'b1;
|
||||||
o_jump_length <= 3'd4;
|
o_jump_length <= 3'd4;
|
||||||
jump_counter <= 3'd0;
|
jump_counter <= 3'd0;
|
||||||
o_instr_execute <= 1'b1;
|
o_instr_execute <= 1'b1;
|
||||||
|
@ -316,6 +342,30 @@ always @(posedge i_clk) begin
|
||||||
decode_started <= 1'b0;
|
decode_started <= 1'b0;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if (block_82x) begin
|
||||||
|
`ifdef SIM
|
||||||
|
$write("DECODER %0d: [%d] block_82x ", i_phase, i_cycle_ctr);
|
||||||
|
case (i_nibble)
|
||||||
|
4'h1: $display("XM=0");
|
||||||
|
4'h2: $display("SB=0");
|
||||||
|
4'h4: $display("SR=0");
|
||||||
|
4'h8: $display("MP=0");
|
||||||
|
4'hF: $display("CLRHST");
|
||||||
|
default: $display("CLRHST %h", i_nibble);
|
||||||
|
endcase
|
||||||
|
`endif
|
||||||
|
o_alu_reg_dest <= `ALU_REG_HST;
|
||||||
|
o_alu_reg_src_1 <= `ALU_REG_IMM;
|
||||||
|
o_alu_reg_src_2 <= `ALU_REG_NONE;
|
||||||
|
o_alu_imm_value <= i_nibble;
|
||||||
|
o_alu_opcode <= `ALU_OP_CLR_MASK;
|
||||||
|
o_instr_type <= `INSTR_TYPE_ALU;
|
||||||
|
o_instr_decoded <= 1'b1;
|
||||||
|
o_instr_execute <= 1'b1;
|
||||||
|
block_82x <= 1'b0;
|
||||||
|
decode_started <= 1'b0;
|
||||||
|
end
|
||||||
|
|
||||||
if (block_84x_85x) begin
|
if (block_84x_85x) begin
|
||||||
o_alu_ptr_begin <= i_nibble;
|
o_alu_ptr_begin <= i_nibble;
|
||||||
o_alu_ptr_end <= i_nibble;
|
o_alu_ptr_end <= i_nibble;
|
||||||
|
@ -370,11 +420,13 @@ always @(posedge i_clk) begin
|
||||||
just_reset <= 1'b1;
|
just_reset <= 1'b1;
|
||||||
decode_started <= 1'b0;
|
decode_started <= 1'b0;
|
||||||
|
|
||||||
|
block_0x <= 1'b0;
|
||||||
block_2x <= 1'b0;
|
block_2x <= 1'b0;
|
||||||
block_6x <= 1'b0;
|
block_6x <= 1'b0;
|
||||||
block_8x <= 1'b0;
|
block_8x <= 1'b0;
|
||||||
block_80x <= 1'b0;
|
block_80x <= 1'b0;
|
||||||
block_80Cx <= 1'b0;
|
block_80Cx <= 1'b0;
|
||||||
|
block_82x <= 1'b0;
|
||||||
block_84x_85x <= 1'b0;
|
block_84x_85x <= 1'b0;
|
||||||
|
|
||||||
block_JUMP <= 1'b0;
|
block_JUMP <= 1'b0;
|
||||||
|
|
Loading…
Reference in a new issue