implement CLRHST and variants

implement SET[HEX|DEC]
This commit is contained in:
Raphaël Jacquot 2019-03-04 10:53:37 +01:00
parent 735504d2b3
commit 908b96df6f
6 changed files with 112 additions and 16 deletions

View file

@ -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

View file

@ -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),

View file

@ -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;

View file

@ -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;

View file

@ -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

View file

@ -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;