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
`ifdef SIM
if (cycle_ctr == 65) begin
if (cycle_ctr == 85) begin
bus_halt <= 1'b1;
$display("BUS %0d: [%d] enough cycles for now", phase, cycle_ctr);
end

View file

@ -79,6 +79,7 @@ saturn_control_unit control_unit (
/* debugger interface */
.o_current_pc (ctrl_current_pc),
.o_reg_alu_mode (ctrl_reg_alu_mode),
.o_reg_hst (ctrl_reg_hst),
.o_reg_st (ctrl_reg_st),
.o_reg_p (ctrl_reg_p),
@ -104,6 +105,7 @@ wire [0:0] ctrl_unit_no_read;
/* debugger insterface */
wire [19:0] ctrl_current_pc;
wire [0:0] ctrl_reg_alu_mode;
wire [3:0] ctrl_reg_hst;
wire [15:0] ctrl_reg_st;
wire [3:0] ctrl_reg_p;
@ -137,6 +139,7 @@ saturn_debugger debugger (
/* debugger interface */
.i_current_pc (ctrl_current_pc),
.i_reg_alu_mode (ctrl_reg_alu_mode),
.i_reg_hst (ctrl_reg_hst),
.i_reg_st (ctrl_reg_st),
.i_reg_p (ctrl_reg_p),

View file

@ -45,6 +45,7 @@ module saturn_control_unit (
/* debugger interface */
o_current_pc,
o_reg_alu_mode,
o_reg_p,
o_reg_hst,
o_reg_st,
@ -85,6 +86,8 @@ assign o_error = control_unit_error || dec_error;
/* debugger interface */
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_hst;
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_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_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_dest_c = (dec_alu_reg_dest == `ALU_REG_C);
wire [0:0] reg_dest_hst = (dec_alu_reg_dest == `ALU_REG_HST);
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_imm = (dec_alu_reg_src_1 == `ALU_REG_IMM);
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] 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_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_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_HST;
reg [15:0] reg_ST;
reg [3:0] reg_P;
wire [19:0] reg_PC;
wire [0:0] reload_PC;
always @(*) begin
always @(i_dbg_register, i_dbg_reg_ptr) begin
case (i_dbg_register)
`ALU_REG_C: o_dbg_reg_nibble <= reg_C[i_dbg_reg_ptr];
default: o_dbg_reg_nibble <= 4'h0;
@ -277,6 +287,7 @@ initial begin
load_pc_loop = 1'b0;
/* registers */
reg_alu_mode = 1'b0;
reg_HST = 4'b0;
reg_ST = 16'b0;
reg_P = 4'b0;
@ -383,6 +394,20 @@ always @(posedge i_clk) begin
reg_C[dec_alu_ptr_begin] <= reg_P;
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 */
if (inst_alu_st_eq_01_n) begin
@ -394,6 +419,18 @@ always @(posedge i_clk) begin
* the general case
*/
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_RESET:
begin
@ -430,6 +467,7 @@ always @(posedge i_clk) begin
load_pc_loop <= 1'b0;
/* registers */
reg_alu_mode <= 1'b0;
reg_HST <= 4'b0;
reg_ST <= 16'b0;
reg_P <= 4'b0;

View file

@ -35,6 +35,7 @@ module saturn_debugger (
/* interface from the control unit */
i_current_pc,
i_reg_alu_mode,
i_reg_hst,
i_reg_st,
i_reg_p,
@ -67,6 +68,7 @@ output reg [0:0] o_debug_cycle;
/* inteface from the control unit */
input wire [19:0] i_current_pc;
input wire [0:0] i_reg_alu_mode;
input wire [3:0] i_reg_hst;
input wire [15:0] i_reg_st;
input wire [3:0] i_reg_p;
@ -227,9 +229,9 @@ always @(posedge i_clk) begin
5'd0: registers_str[registers_ctr] <= "h";
5'd1: 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'd5: registers_str[registers_ctr] <= "@";
5'd5: registers_str[registers_ctr] <= i_reg_alu_mode?"C":"X";
5'd6: registers_str[registers_ctr] <= " ";
endcase
registers_reg_ptr <= registers_reg_ptr + 5'd1;

View file

@ -97,11 +97,12 @@
*/
`define INSTR_TYPE_NOP 0
`define INSTR_TYPE_ALU 1
`define INSTR_TYPE_JUMP 2
`define INSTR_TYPE_RESET 3
`define INSTR_TYPE_NOP 0
`define INSTR_TYPE_ALU 1
`define INSTR_TYPE_SET_MODE 2
`define INSTR_TYPE_JUMP 3
`define INSTR_TYPE_RESET 4
`define INSTR_TYPE_NONE 15
`define INSTR_TYPE_NONE 15
`endif

View file

@ -121,11 +121,13 @@ reg [0:0] decode_started;
* decoder block variables
*/
reg [0:0] block_0x;
reg [0:0] block_2x;
reg [0:0] block_6x;
reg [0:0] block_8x;
reg [0:0] block_80x;
reg [0:0] block_80Cx;
reg [0:0] block_82x;
reg [0:0] block_84x_85x;
reg [0:0] block_JUMP;
@ -159,11 +161,13 @@ initial begin
just_reset = 1'b1;
decode_started = 1'b0;
block_0x = 1'b0;
block_2x = 1'b0;
block_6x = 1'b0;
block_8x = 1'b0;
block_80x = 1'b0;
block_80Cx = 1'b0;
block_82x = 1'b0;
block_84x_85x = 1'b0;
block_JUMP = 1'b0;
@ -208,6 +212,7 @@ always @(posedge i_clk) begin
decode_started <= 1'b1;
case (i_nibble)
4'h0: block_0x <= 1'b1;
4'h2: block_2x <= 1'b1;
4'h6:
begin
@ -229,6 +234,25 @@ always @(posedge i_clk) begin
if (i_phases[2] && decode_started) begin
$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
o_alu_reg_dest <= `ALU_REG_P;
o_alu_reg_src_1 <= `ALU_REG_IMM;
@ -255,6 +279,7 @@ always @(posedge i_clk) begin
if (block_8x) begin
case (i_nibble)
4'h0: block_80x <= 1'b1;
4'h2: block_82x <= 1'b1;
4'h4, 4'h5:
begin
o_alu_reg_dest <= `ALU_REG_ST;
@ -265,9 +290,10 @@ always @(posedge i_clk) begin
o_instr_type <= `INSTR_TYPE_ALU;
block_84x_85x <= 1'b1;
end
4'hD:
4'hD, 4'hF:
begin
o_instr_type <= `INSTR_TYPE_JUMP;
o_push_pc <= 1'b1;
o_jump_length <= 3'd4;
jump_counter <= 3'd0;
o_instr_execute <= 1'b1;
@ -316,6 +342,30 @@ always @(posedge i_clk) begin
decode_started <= 1'b0;
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
o_alu_ptr_begin <= i_nibble;
o_alu_ptr_end <= i_nibble;
@ -370,11 +420,13 @@ always @(posedge i_clk) begin
just_reset <= 1'b1;
decode_started <= 1'b0;
block_0x <= 1'b0;
block_2x <= 1'b0;
block_6x <= 1'b0;
block_8x <= 1'b0;
block_80x <= 1'b0;
block_80Cx <= 1'b0;
block_82x <= 1'b0;
block_84x_85x <= 1'b0;
block_JUMP <= 1'b0;