Line 28... |
Line 28... |
input wire set_e,
|
input wire set_e,
|
input wire clear_e,
|
input wire clear_e,
|
output wire [7:0] CCR_o,
|
output wire [7:0] CCR_o,
|
output reg [15:0] path_left_data,
|
output reg [15:0] path_left_data,
|
output reg [15:0] path_right_data,
|
output reg [15:0] path_right_data,
|
output reg [15:0] eamem_addr,
|
output wire [15:0] eamem_addr_o,
|
output wire [15:0] reg_pc,
|
output wire [15:0] reg_pc,
|
output wire [7:0] reg_dp,
|
output wire [7:0] reg_dp,
|
output wire [15:0] reg_su
|
output wire [15:0] reg_su
|
);
|
);
|
|
|
Line 48... |
Line 48... |
reg [7:0] DP;
|
reg [7:0] DP;
|
`define CCR { eflag, fflag, hflag, intff, nff, zff, vff, cff }
|
`define CCR { eflag, fflag, hflag, intff, nff, zff, vff, cff }
|
|
|
reg eflag, fflag, hflag;
|
reg eflag, fflag, hflag;
|
reg intff, nff, zff, vff, cff;
|
reg intff, nff, zff, vff, cff;
|
reg [15:0] ea_reg, ea_reg_post;
|
wire [15:0] eamem_addr, ea_reg_post;
|
|
|
assign CCR_o = `CCR;
|
assign CCR_o = `CCR;
|
assign reg_pc = PC;
|
assign reg_pc = PC;
|
assign reg_dp = DP;
|
assign reg_dp = DP;
|
assign reg_su = (use_s) ? SS:SU; /* stack pointer */
|
assign reg_su = (use_s) ? SS:SU; /* stack pointer */
|
|
|
|
calc_ea ea(eapostbyte,
|
|
offset16,
|
|
ACCA,
|
|
ACCB,
|
|
IX,
|
|
IY,
|
|
SS,
|
|
SU,
|
|
PC,
|
|
eamem_addr,
|
|
ea_reg_post);
|
|
|
|
assign eamem_addr_o = eamem_addr;
|
|
|
// left path output, always 16 bits
|
// left path output, always 16 bits
|
always @(*)
|
always @(*)
|
begin
|
begin
|
case (path_left_addr)
|
case (path_left_addr)
|
`RN_ACCA: path_left_data = { 8'hff, ACCA };
|
`RN_ACCA: path_left_data = { 8'hff, ACCA };
|
Line 84... |
Line 99... |
`RN_ACCD: path_right_data = `ACCD;
|
`RN_ACCD: path_right_data = `ACCD;
|
`RN_IX: path_right_data = IX;
|
`RN_IX: path_right_data = IX;
|
`RN_IY: path_right_data = IY;
|
`RN_IY: path_right_data = IY;
|
`RN_U: path_right_data = SU;
|
`RN_U: path_right_data = SU;
|
`RN_S: path_right_data = SS;
|
`RN_S: path_right_data = SS;
|
|
`RN_PC: path_right_data = PC;
|
`RN_DP: path_right_data = { DP, DP };
|
`RN_DP: path_right_data = { DP, DP };
|
`RN_CC: path_right_data = { `CCR, `CCR };
|
`RN_CC: path_right_data = { `CCR, `CCR };
|
default:
|
default:
|
path_right_data = 16'hFFFF;
|
path_right_data = 16'hFFFF;
|
endcase
|
endcase
|
end
|
end
|
|
|
|
wire [15:0] left, right;
|
|
wire [3:0] right_reg;
|
|
wire [15:0] pc_plus_1;
|
|
assign pc_plus_1 = PC + 16'h0001;
|
|
|
|
assign left = (write_tfr | write_exg) ? path_left_data:data_w;
|
|
|
|
assign right = (inc_pc) ? pc_plus_1:path_right_data;
|
|
|
|
assign right_reg = (inc_pc | write_pc) ? `RN_PC:exg_dest_r;
|
|
|
|
always @(posedge clk_in)
|
|
begin
|
|
if (write_exg | inc_pc | write_pc)
|
|
case (right_reg)
|
|
0: `ACCD <= right;
|
|
1: IX <= right;
|
|
2: IY <= right;
|
|
3: SU <= right;
|
|
4: SS <= right;
|
|
5: PC <= right;
|
|
8: ACCA <= right[7:0];
|
|
9: ACCB <= right[7:0];
|
|
10: `CCR <= right[7:0];
|
|
11: DP <= right[7:0];
|
|
endcase
|
|
if (write_tfr | write_exg | write_reg)
|
|
case (write_reg_addr)
|
|
0: `ACCD <= left;
|
|
1: IX <= left;
|
|
2: IY <= left;
|
|
3: SU <= left;
|
|
4: SS <= left;
|
|
5: PC <= left;
|
|
8: ACCA <= left[7:0];
|
|
9: ACCB <= left[7:0];
|
|
10: `CCR <= left[7:0];
|
|
11: DP <= left[7:0];
|
|
endcase
|
|
if (write_post) // write back predecrement/postincremented values
|
|
begin
|
|
case (eapostbyte[6:5])
|
|
2'b00: IX <= ea_reg_post;
|
|
2'b01: IY <= ea_reg_post;
|
|
2'b10: SU <= ea_reg_post;
|
|
2'b11: SS <= ea_reg_post;
|
|
endcase
|
|
end
|
|
if (write_flags)
|
|
begin
|
|
`CCR <= CCR_in;
|
|
end
|
|
if (set_e | clear_e) eflag <= set_e;
|
|
//if (clear_e) eflag <= 0;
|
|
if (write_pc) PC <= new_pc;
|
|
//if (inc_pc) PC <= PC + 16'h1;
|
|
if (inc_su)
|
|
if (use_s) SS <= SS + 16'h1;
|
|
else SU <= SU + 16'h1;
|
|
if (dec_su)
|
|
if (use_s) SS <= SS - 16'h1;
|
|
else SU <= SU - 16'h1;
|
|
end
|
|
|
|
`ifdef SIMULATION
|
|
initial
|
|
begin
|
|
PC = 16'hfffe;
|
|
DP = 8'h00;
|
|
IX = 16'h0;
|
|
`CCR = 0;
|
|
IY = 16'hA55A;
|
|
SS = 16'h0f00;
|
|
SU = 16'h0e00;
|
|
end
|
|
`endif
|
|
endmodule
|
|
|
|
|
|
module calc_ea(
|
|
input wire [7:0] eapostbyte,
|
|
input wire [15:0] offset16,
|
|
input wire [7:0] acca,
|
|
input wire [7:0] accb,
|
|
input wire [15:0] ix,
|
|
input wire [15:0] iy,
|
|
input wire [15:0] s,
|
|
input wire [15:0] u,
|
|
input wire [15:0] pc,
|
|
output wire [15:0] eamem_addr_o,
|
|
output wire [15:0] ea_reg_post_o
|
|
);
|
|
|
|
reg [15:0] ea_reg, ea_reg_post, eamem_addr;
|
|
|
|
assign eamem_addr_o = eamem_addr;
|
|
assign ea_reg_post_o = ea_reg_post;
|
|
|
always @(*)
|
always @(*)
|
begin
|
begin
|
case (eapostbyte[6:5])
|
case (eapostbyte[6:5])
|
2'b00: ea_reg = IX;
|
2'b00: ea_reg = ix;
|
2'b01: ea_reg = IY;
|
2'b01: ea_reg = iy;
|
2'b10: ea_reg = SU;
|
2'b10: ea_reg = u;
|
2'b11: ea_reg = SS;
|
2'b11: ea_reg = s;
|
endcase
|
endcase
|
end
|
end
|
// pre-decrement/postincrement
|
// pre-decrement/postincrement
|
always @(*)
|
always @(*)
|
begin
|
begin
|
ea_reg_post = ea_reg;
|
case (eapostbyte[1:0])
|
casex (eapostbyte)
|
2'b00: ea_reg_post = ea_reg + 16'h1;
|
8'b1xxx0000: ea_reg_post = ea_reg + 16'h1;
|
2'b01: ea_reg_post = ea_reg + 16'h2;
|
8'b1xxx0001: ea_reg_post = ea_reg + 16'h2;
|
2'b10: ea_reg_post = ea_reg - 16'h1;
|
8'b1xxx0010: ea_reg_post = ea_reg - 16'h1;
|
2'b11: ea_reg_post = ea_reg - 16'h2;
|
8'b1xxx0011: ea_reg_post = ea_reg - 16'h2;
|
|
//default: ea_reg_post = ea_reg;
|
|
endcase
|
endcase
|
end
|
end
|
|
|
/* EA calculation
|
/* EA calculation
|
* postbyte bytes assembler
|
* postbyte bytes assembler
|
Line 152... |
Line 264... |
eamem_addr = ea_reg;
|
eamem_addr = ea_reg;
|
8'b1xx_x_0010, // pre decrement
|
8'b1xx_x_0010, // pre decrement
|
8'b1xx_x_0011: // pre decrement
|
8'b1xx_x_0011: // pre decrement
|
eamem_addr = ea_reg_post; // gets precalculated pre-decremented address
|
eamem_addr = ea_reg_post; // gets precalculated pre-decremented address
|
8'b1xx_x_0101: // B,R
|
8'b1xx_x_0101: // B,R
|
eamem_addr = ea_reg + { {8{ACCB[7]}}, ACCB };
|
eamem_addr = ea_reg + { {8{accb[7]}}, accb };
|
8'b1xx_x_0110: // A,R
|
8'b1xx_x_0110: // A,R
|
eamem_addr = ea_reg + { {8{ACCA[7]}}, ACCA };
|
eamem_addr = ea_reg + { {8{acca[7]}}, acca };
|
8'b1xx_x_1011: // D,R
|
8'b1xx_x_1011: // D,R
|
eamem_addr = ea_reg + `ACCD;
|
eamem_addr = ea_reg + { acca, accb };
|
8'b1xx_x_1000: // n,R 8 bit offset
|
8'b1xx_x_1000: // n,R 8 bit offset
|
eamem_addr = ea_reg + { offset16[7] ? 8'hff:8'h0, offset16[7:0] }; // from postbyte1
|
eamem_addr = ea_reg + { offset16[7] ? 8'hff:8'h0, offset16[7:0] }; // from postbyte1
|
8'b1xx_x_1001: // n,R // 16 bit offset
|
8'b1xx_x_1001: // n,R // 16 bit offset
|
eamem_addr = ea_reg + offset16;
|
eamem_addr = ea_reg + offset16;
|
8'b1xx_x_1100: // n,PC
|
8'b1xx_x_1100: // n,PC
|
eamem_addr = PC + { offset16[7] ? 8'hff:8'h0, offset16[7:0] };
|
eamem_addr = pc + { offset16[7] ? 8'hff:8'h0, offset16[7:0] };
|
8'b1xx_x_1101: // n,PC
|
8'b1xx_x_1101: // n,PC
|
eamem_addr = PC + offset16;
|
eamem_addr = pc + offset16;
|
endcase
|
endcase
|
end
|
end
|
|
|
wire [15:0] left;
|
|
|
|
assign left = (write_tfr | write_exg) ? path_left_data:data_w;
|
|
|
|
//wire [15:0] new_su, old_su;
|
|
|
|
//assign old_su = (use_s) ? SS:SU;
|
|
//assign new_su = (inc_su) ? old_su + 16'h1:(dec_su) ? old_su - 16'h1:old_su;
|
|
|
|
always @(posedge clk_in)
|
|
begin
|
|
if (write_exg)
|
|
case (exg_dest_r)
|
|
0: `ACCD <= path_right_data;
|
|
1: IX <= path_right_data;
|
|
2: IY <= path_right_data;
|
|
3: SU <= path_right_data;
|
|
4: SS <= path_right_data;
|
|
5: PC <= path_right_data;
|
|
8: ACCA <= path_right_data[7:0];
|
|
9: ACCB <= path_right_data[7:0];
|
|
10: `CCR <= path_right_data[7:0];
|
|
11: DP <= path_right_data[7:0];
|
|
endcase
|
|
if (write_tfr | write_exg | write_reg)
|
|
case (write_reg_addr)
|
|
0: `ACCD <= left;
|
|
1: IX <= left;
|
|
2: IY <= left;
|
|
3: SU <= left;
|
|
4: SS <= left;
|
|
5: PC <= left;
|
|
8: ACCA <= left[7:0];
|
|
9: ACCB <= left[7:0];
|
|
10: `CCR <= left[7:0];
|
|
11: DP <= left[7:0];
|
|
endcase
|
|
if (write_post) // write back predecrement/postincremented values
|
|
begin
|
|
case (eapostbyte[6:5])
|
|
2'b00: IX <= ea_reg_post;
|
|
2'b01: IY <= ea_reg_post;
|
|
2'b10: SU <= ea_reg_post;
|
|
2'b11: SS <= ea_reg_post;
|
|
endcase
|
|
end
|
|
if (write_flags)
|
|
begin
|
|
`CCR <= CCR_in;
|
|
end
|
|
if (set_e) eflag <= 1;
|
|
if (clear_e) eflag <= 0;
|
|
if (write_pc) PC <= new_pc;
|
|
if (inc_pc) PC <= PC + 16'h1;
|
|
/*
|
|
if (inc_su | dec_su)
|
|
begin
|
|
if (use_s) SS <= new_su;
|
|
else SU <= new_su;
|
|
end
|
|
*/
|
|
if (inc_su)
|
|
if (use_s) SS <= SS + 16'h1;
|
|
else SU <= SU + 16'h1;
|
|
if (dec_su)
|
|
if (use_s) SS <= SS - 16'h1;
|
|
else SU <= SU - 16'h1;
|
|
end
|
|
|
|
`ifdef SIMULATION
|
|
initial
|
|
begin
|
|
PC = 16'hfffe;
|
|
DP = 8'h00;
|
|
IX = 16'h0;
|
|
`CCR = 0;
|
|
IY = 16'hA55A;
|
|
SS = 16'h0f00;
|
|
SU = 16'h0e00;
|
|
end
|
|
`endif
|
|
endmodule
|
endmodule
|
|
|
No newline at end of file
|
No newline at end of file
|