Line 8... |
Line 8... |
*
|
*
|
*
|
*
|
*
|
*
|
*/
|
*/
|
`include "defs.v"
|
`include "defs.v"
|
module alu16(
|
|
input wire clk,
|
|
|
module alu(
|
|
input wire clk_in,
|
input wire [15:0] a_in,
|
input wire [15:0] a_in,
|
input wire [15:0] b_in,
|
input wire [15:0] b_in,
|
input wire [7:0] CCR, /* condition code register */
|
input wire [7:0] CCR, /* condition code register */
|
input wire [4:0] opcode_in, /* ALU opcode */
|
input wire [4:0] opcode_in, /* ALU opcode */
|
input wire sz_in, /* size, low 8 bit, high 16 bit */
|
input wire sz_in, /* size, low 8 bit, high 16 bit */
|
output reg [15:0] q_out, /* ALU result */
|
output reg [15:0] q_out, /* ALU result */
|
output reg [7:0] CCRo
|
output reg [7:0] CCRo
|
);
|
);
|
|
|
|
wire [7:0] ccr8_out, q8_out;
|
|
wire [15:0] q16_out;
|
|
wire [3:0] ccr16_out;
|
|
|
|
reg [15:0] ra_in, rb_in;
|
|
|
|
alu8 alu8(clk_in, ra_in[7:0], rb_in[7:0], CCR, opcode_in, q8_out, ccr8_out);
|
|
alu16 alu16(clk_in, ra_in, rb_in, CCR, opcode_in, q16_out, ccr16_out);
|
|
|
|
always @(posedge clk_in)
|
|
begin
|
|
ra_in <= a_in;
|
|
rb_in <= b_in;
|
|
end
|
|
|
|
always @(*)
|
|
begin
|
|
if (sz_in)
|
|
begin
|
|
q_out = q16_out;
|
|
CCRo = { CCR[7:4], ccr16_out };
|
|
end
|
|
else
|
|
begin
|
|
q_out = { 8'h0, q8_out };
|
|
CCRo = ccr8_out;
|
|
end
|
|
end
|
|
|
|
endmodule
|
|
|
|
module alu8(
|
|
input wire clk_in,
|
|
input wire [15:0] a_in,
|
|
input wire [15:0] b_in,
|
|
input wire [7:0] CCR, /* condition code register */
|
|
input wire [4:0] opcode_in, /* ALU opcode */
|
|
output reg [7:0] q_out, /* ALU result */
|
|
output reg [7:0] CCRo
|
|
);
|
|
|
wire c_in, n_in, v_in, z_in, h_in;
|
wire c_in, n_in, v_in, z_in, h_in;
|
assign c_in = CCR[0]; /* carry flag */
|
assign c_in = CCR[0]; /* carry flag */
|
assign n_in = CCR[3]; /* neg flag */
|
assign n_in = CCR[3]; /* neg flag */
|
assign v_in = CCR[1]; /* overflow flag */
|
assign v_in = CCR[1]; /* overflow flag */
|
assign z_in = CCR[2]; /* zero flag */
|
assign z_in = CCR[2]; /* zero flag */
|
assign h_in = CCR[5]; /* halb-carry flag */
|
assign h_in = CCR[5]; /* halb-carry flag */
|
|
|
|
|
wire [7:0] add8_r, adc8_r, sub8_r, sbc8_r, com8_r, neg8_r;
|
wire [7:0] add8_r, adc8_r, sub8_r, sbc8_r, com8_r, neg8_r;
|
wire [7:0] asr8_r, shr8_r, shl8_r, ror8_r, rol8_r, and8_r, or8_r, eor8_r;
|
wire [7:0] asr8_r, shr8_r, shl8_r, ror8_r, rol8_r, and8_r, or8_r, eor8_r;
|
wire [15:0] add16_r, adc16_r, sub16_r, sbc16_r, com16_r, neg16_r;
|
|
wire [15:0] asr16_r, shr16_r, shl16_r, ror16_r, rol16_r, and16_r, or16_r, eor16_r, mul16_r;
|
|
wire [3:0] daa8l_r, daa8h_r;
|
wire [3:0] daa8l_r, daa8h_r;
|
wire daa_lnm9;
|
wire daa_lnm9;
|
|
|
wire [7:0] add8_w, adc8_w, com8_w, neg8_w, sub8_w, sbc8_w;
|
wire [7:0] add8_w, adc8_w, com8_w, neg8_w, sub8_w, sbc8_w;
|
wire [7:0] asr8_w, shr8_w, shl8_w, ror8_w, rol8_w, and8_w, or8_w, eor8_w;
|
wire [7:0] asr8_w, shr8_w, shl8_w, ror8_w, rol8_w, and8_w, or8_w, eor8_w;
|
wire [15:0] add16_w, adc16_w, com16_w, neg16_w, sub16_w, sbc16_w;
|
|
wire [15:0] asr16_w, shr16_w, shl16_w, ror16_w, rol16_w, and16_w, or16_w, eor16_w, mul16_w;
|
|
|
|
wire cadd8_w, cadc8_w, csub8_w, csbc8_w;
|
wire cadd8_w, cadc8_w, csub8_w, csbc8_w;
|
wire cadd16_w, cadc16_w, csub16_w, csbc16_w;
|
wire cadd16_w, cadc16_w, csub16_w, csbc16_w;
|
|
|
wire cadd8_r, cadc8_r, csub8_r, csbc8_r, ccom8_r, cneg8_r;
|
wire cadd8_r, cadc8_r, csub8_r, csbc8_r, ccom8_r, cneg8_r;
|
wire casr8_r, cshr8_r, cshl8_r, cror8_r, crol8_r, cand8_r, cdaa8_r;
|
wire casr8_r, cshr8_r, cshl8_r, cror8_r, crol8_r, cand8_r, cdaa8_r;
|
wire cadd16_r, cadc16_r, csub16_r, csbc16_r, ccom16_r, cneg16_r;
|
|
wire casr16_r, cshr16_r, cshl16_r, cror16_r, crol16_r, cand16_r, cmul16_r;
|
|
wire vadd8_r, vadc8_r, vsub8_r, vsbc8_r, vcom8_r, vneg8_r;
|
wire vadd8_r, vadc8_r, vsub8_r, vsbc8_r, vcom8_r, vneg8_r;
|
wire vasr8_r, vshr8_r, vshl8_r, vror8_r, vrol8_r, vand8_r;
|
wire vasr8_r, vshr8_r, vshl8_r, vror8_r, vrol8_r, vand8_r;
|
wire vadd16_r, vadc16_r, vsub16_r, vsbc16_r, vcom16_r, vneg16_r;
|
|
wire vasr16_r, vshr16_r, vshl16_r, vror16_r, vrol16_r, vand16_r;
|
|
|
|
assign { cadd8_w, add8_w } = { 1'b0, a_in[7:0] } + { 1'b0, b_in[7:0] };
|
assign { cadd8_w, add8_w } = { 1'b0, a_in[7:0] } + { 1'b0, b_in[7:0] };
|
assign { cadd16_w, add16_w } = { 1'b0, a_in[15:0] } + { 1'b0, b_in[15:0] };
|
|
assign { cadc8_w, adc8_w } = { 1'b0, a_in[7:0] } + { 1'b0, b_in[7:0] } + { 8'h0, c_in };
|
assign { cadc8_w, adc8_w } = { 1'b0, a_in[7:0] } + { 1'b0, b_in[7:0] } + { 8'h0, c_in };
|
assign { cadc16_w, adc16_w } = { 1'b0, a_in[15:0] } + { 1'b0, b_in[15:0] } + { 16'h0, c_in };
|
|
|
|
assign { csub8_w, sub8_w } = { 1'b0, a_in[7:0] } - { 1'b0, b_in[7:0] };
|
assign { csub8_w, sub8_w } = { 1'b0, a_in[7:0] } - { 1'b0, b_in[7:0] };
|
assign { csub16_w, sub16_w } = { 1'b0, a_in[15:0] } - { 1'b0, b_in[15:0] };
|
|
assign { csbc8_w, sbc8_w } = { 1'b0, a_in[7:0] } - { 1'b0, b_in[7:0] } - { 8'h0, c_in };
|
assign { csbc8_w, sbc8_w } = { 1'b0, a_in[7:0] } - { 1'b0, b_in[7:0] } - { 8'h0, c_in };
|
assign { csbc16_w, sbc16_w } = { 1'b0, a_in[15:0] } - { 1'b0, b_in[15:0] } - { 16'h0, c_in };
|
|
|
|
assign com8_w = ~a_in[7:0];
|
assign com8_w = ~a_in[7:0];
|
assign com16_w = ~a_in[15:0];
|
|
assign neg8_w = 8'h0 - a_in[7:0];
|
assign neg8_w = 8'h0 - a_in[7:0];
|
assign neg16_w = 16'h0 - a_in[15:0];
|
|
|
|
assign asr8_w = { a_in[7], a_in[7:1] };
|
assign asr8_w = { a_in[7], a_in[7:1] };
|
assign asr16_w = { a_in[15], a_in[15:1] };
|
|
|
|
assign shr8_w = { 1'b0, a_in[7:1] };
|
assign shr8_w = { 1'b0, a_in[7:1] };
|
assign shr16_w = { 1'b0, a_in[15:1] };
|
|
|
|
assign shl8_w = { a_in[6:0], 1'b0 };
|
assign shl8_w = { a_in[6:0], 1'b0 };
|
assign shl16_w = { a_in[14:0], 1'b0 };
|
|
|
|
assign ror8_w = { c_in, a_in[7:1] };
|
assign ror8_w = { c_in, a_in[7:1] };
|
assign ror16_w = { c_in, a_in[15:1] };
|
|
|
|
assign rol8_w = { a_in[6:0], c_in };
|
assign rol8_w = { a_in[6:0], c_in };
|
assign rol16_w = { a_in[14:0], c_in };
|
|
|
|
assign and8_w = a_in[7:0] & b_in[7:0];
|
assign and8_w = a_in[7:0] & b_in[7:0];
|
assign and16_w = a_in[15:0] & b_in[15:0];
|
|
|
|
assign or8_w = a_in[7:0] | b_in[7:0];
|
assign or8_w = a_in[7:0] | b_in[7:0];
|
assign or16_w = a_in[15:0] | b_in[15:0];
|
|
|
|
assign eor8_w = a_in[7:0] ^ b_in[7:0];
|
assign eor8_w = a_in[7:0] ^ b_in[7:0];
|
assign eor16_w = a_in[15:0] ^ b_in[15:0];
|
|
assign mul16_w = a_in[7:0] * b_in[7:0];
|
|
|
|
// ADD, ADC
|
// ADD, ADC
|
assign { cadd8_r, add8_r } = { cadd8_w, add8_w };
|
assign { cadd8_r, add8_r } = { cadd8_w, add8_w };
|
assign vadd8_r = (a_in[7] & b_in[7] & (~add8_w[7])) | ((~a_in[7]) & (~b_in[7]) & add8_w[7]);
|
assign vadd8_r = (a_in[7] & b_in[7] & (~add8_w[7])) | ((~a_in[7]) & (~b_in[7]) & add8_w[7]);
|
assign { cadd16_r, add16_r } = { cadd16_w, add16_w };
|
|
assign vadd16_r = (a_in[15] & b_in[15] & (~add16_w[15])) | ((~a_in[15]) & (~b_in[15]) & add16_w[15]);
|
|
assign { cadc8_r, adc8_r } = { cadd8_w, add8_w };
|
assign { cadc8_r, adc8_r } = { cadd8_w, add8_w };
|
assign vadc8_r = (a_in[7] & b_in[7] & (~add8_w[7])) | ((~a_in[7]) & (~b_in[7]) & adc8_w[7]);
|
assign vadc8_r = (a_in[7] & b_in[7] & (~add8_w[7])) | ((~a_in[7]) & (~b_in[7]) & adc8_w[7]);
|
assign { cadc16_r, adc16_r } = { cadd16_w, add16_w };
|
|
assign vadc16_r = (a_in[15] & b_in[15] & (~add16_w[15])) | ((~a_in[15]) & (~b_in[15]) & adc16_w[15]);
|
|
// SUB, SUBC
|
// SUB, SUBC
|
assign { csub8_r, sub8_r } = { csub8_w, sub8_w };
|
assign { csub8_r, sub8_r } = { csub8_w, sub8_w };
|
assign vsub8_r = (a_in[7] & (~b_in[7]) & (~sub8_w[7])) | ((~a_in[7]) & b_in[7] & sub8_w[7]);
|
assign vsub8_r = (a_in[7] & (~b_in[7]) & (~sub8_w[7])) | ((~a_in[7]) & b_in[7] & sub8_w[7]);
|
assign { csub16_r, sub16_r } = { csub16_w, sub16_w };
|
|
assign vsub16_r = (a_in[15] & b_in[15] & (~add16_w[15])) | ((~a_in[15]) & b_in[15] & sub16_w[15]);
|
|
assign { csbc8_r, sbc8_r } = { csbc8_w, sbc8_w };
|
assign { csbc8_r, sbc8_r } = { csbc8_w, sbc8_w };
|
assign vsbc8_r = (a_in[7] & b_in[7] | (~sbc8_w[7])) | ((~a_in[7]) & b_in[7] & sbc8_w[7]);
|
assign vsbc8_r = (a_in[7] & b_in[7] | (~sbc8_w[7])) | ((~a_in[7]) & b_in[7] & sbc8_w[7]);
|
assign { csbc16_r, sbc16_r } = { csbc16_w, sbc16_w };
|
|
assign vsbc16_r = (a_in[15] & b_in[15] & (~sbc16_w[15])) | ((~a_in[15]) & b_in[15] & sbc16_w[15]);
|
|
// COM
|
// COM
|
assign com8_r = com8_w;
|
assign com8_r = com8_w;
|
assign ccom8_r = com8_w != 8'h0 ? 1'b1:1'b0;
|
assign ccom8_r = com8_w != 8'h0 ? 1'b1:1'b0;
|
assign vcom8_r = 1'b0;
|
assign vcom8_r = 1'b0;
|
assign com16_r = com16_w;
|
|
assign ccom16_r = com16_w != 16'h0 ? 1'b1:1'b0;
|
|
assign vcom16_r = 1'b0;
|
|
// NEG
|
// NEG
|
assign neg8_r = neg8_w;
|
assign neg8_r = neg8_w;
|
assign cneg8_r = neg8_w[7] | neg8_w[6] | neg8_w[5] | neg8_w[4] | neg8_w[3] | neg8_w[2] | neg8_w[1] | neg8_w[0];
|
assign cneg8_r = neg8_w[7] | neg8_w[6] | neg8_w[5] | neg8_w[4] | neg8_w[3] | neg8_w[2] | neg8_w[1] | neg8_w[0];
|
assign vneg8_r = neg8_w[7] & (~neg8_w[6]) & (~neg8_w[5]) & (~neg8_w[4]) & (~neg8_w[3]) & (~neg8_w[2]) & (~neg8_w[1]) & (~neg8_w[0]);
|
assign vneg8_r = neg8_w[7] & (~neg8_w[6]) & (~neg8_w[5]) & (~neg8_w[4]) & (~neg8_w[3]) & (~neg8_w[2]) & (~neg8_w[1]) & (~neg8_w[0]);
|
assign neg16_r = neg16_w;
|
|
assign vneg16_r = neg16_w[15] & (~neg16_w[14]) & (~neg16_w[13]) & (~neg16_w[12]) & (~neg16_w[11]) & (~neg16_w[10]) & (~neg16_w[9]) & (~neg16_w[8]) & (~neg16_w[7]) & (~neg16_w[6]) & (~neg16_w[5]) & (~neg16_w[4]) & (~neg16_w[3]) & (~neg16_w[2]) & (~neg16_w[1]) & (~neg16_w[0]);
|
|
assign cneg16_r = neg16_w[15] | neg16_w[14] | neg16_w[13] | neg16_w[12] | neg16_w[11] | neg16_w[10] | neg16_w[9] & neg16_w[8] | neg16_w[7] | neg16_w[6] | neg16_w[5] | neg16_w[4] | neg16_w[3] | neg16_w[2] | neg16_w[1] | neg16_w[0];
|
|
// ASR
|
// ASR
|
assign asr8_r = asr8_w;
|
assign asr8_r = asr8_w;
|
assign casr8_r = a_in[0];
|
assign casr8_r = a_in[0];
|
assign vasr8_r = a_in[0] ^ asr8_w[7];
|
assign vasr8_r = a_in[0] ^ asr8_w[7];
|
assign asr16_r = asr16_w;
|
|
assign casr16_r = a_in[0];
|
|
assign vasr16_r = a_in[0] ^ asr16_w[15];
|
|
// SHR
|
// SHR
|
assign shr8_r = shr8_w;
|
assign shr8_r = shr8_w;
|
assign cshr8_r = a_in[0];
|
assign cshr8_r = a_in[0];
|
assign vshr8_r = a_in[0] ^ shr8_w[7];
|
assign vshr8_r = a_in[0] ^ shr8_w[7];
|
assign shr16_r = shr16_w;
|
|
assign cshr16_r = a_in[0];
|
|
assign vshr16_r = a_in[0] ^ shr16_w[15];
|
|
// SHL
|
// SHL
|
assign shl8_r = shl8_w;
|
assign shl8_r = shl8_w;
|
assign cshl8_r = a_in[7];
|
assign cshl8_r = a_in[7];
|
assign vshl8_r = a_in[7] ^ shl8_w[7];
|
assign vshl8_r = a_in[7] ^ shl8_w[7];
|
assign shl16_r = shl16_w;
|
|
assign cshl16_r = a_in[15];
|
|
assign vshl16_r = a_in[15] ^ shl16_w[15];
|
|
// ROR
|
// ROR
|
assign ror8_r = ror8_w;
|
assign ror8_r = ror8_w;
|
assign cror8_r = a_in[0];
|
assign cror8_r = a_in[0];
|
assign vror8_r = a_in[0] ^ shr8_w[7];
|
assign vror8_r = a_in[0] ^ shr8_w[7];
|
assign ror16_r = ror16_w;
|
|
assign cror16_r = a_in[0];
|
|
assign vror16_r = a_in[0] ^ ror16_w[15];
|
|
// ROL
|
// ROL
|
assign rol8_r = shl8_w;
|
assign rol8_r = shl8_w;
|
assign crol8_r = a_in[7];
|
assign crol8_r = a_in[7];
|
assign vrol8_r = a_in[7] ^ rol8_w[7];
|
assign vrol8_r = a_in[7] ^ rol8_w[7];
|
assign rol16_r = rol16_w;
|
|
assign crol16_r = a_in[15];
|
|
assign vrol16_r = a_in[15] ^ rol16_w[15];
|
|
// AND
|
// AND
|
assign and8_r = and8_w;
|
assign and8_r = and8_w;
|
assign cand8_r = c_in;
|
assign cand8_r = c_in;
|
assign vand8_r = 1'b0;
|
assign vand8_r = 1'b0;
|
assign and16_r = and16_w;
|
|
assign cand16_r = c_in;
|
|
assign vand16_r = 1'b0;
|
|
// OR
|
// OR
|
assign or8_r = or8_w;
|
assign or8_r = or8_w;
|
assign or16_r = or16_w;
|
|
// EOR
|
// EOR
|
assign eor8_r = eor8_w;
|
assign eor8_r = eor8_w;
|
assign eor16_r = eor16_w;
|
|
// MUL
|
|
assign mul16_r = mul16_w;
|
|
assign cmul16_r = mul16_w[7];
|
|
// DAA
|
// DAA
|
assign daa_lnm9 = (a_in[3:0] > 9);
|
assign daa_lnm9 = (a_in[3:0] > 9);
|
assign daa8l_r = (daa_lnm9 | h_in ) ? a_in[3:0] + 4'h6:a_in[3:0];
|
assign daa8l_r = (daa_lnm9 | h_in ) ? a_in[3:0] + 4'h6:a_in[3:0];
|
assign daa8h_r = ((a_in[7:4] > 9) || (c_in == 1'b1) || (a_in[7] & daa_lnm9)) ? a_in[7:4] + 4'h6:a_in[7:4];
|
assign daa8h_r = ((a_in[7:4] > 9) || (c_in == 1'b1) || (a_in[7] & daa_lnm9)) ? a_in[7:4] + 4'h6:a_in[7:4];
|
assign cdaa8_r = daa8h_r < a_in[7:4];
|
assign cdaa8_r = daa8h_r < a_in[7:4];
|
|
|
reg c8, h8, n8, v8, z8, c16, n16, v16, z16;
|
reg c8, h8, n8, v8, z8;
|
reg [7:0] q8;
|
reg [7:0] q8;
|
reg [15:0] q16;
|
|
|
|
always @(*)
|
always @(*)
|
begin
|
begin
|
q8 = 8'h0;
|
q8 = 8'h0;
|
q16 = 16'h0;
|
|
c8 = c_in;
|
c8 = c_in;
|
h8 = h_in;
|
h8 = h_in;
|
v8 = v_in;
|
v8 = v_in;
|
c16 = c_in;
|
|
v16 = v_in;
|
|
case (opcode_in)
|
case (opcode_in)
|
`ADD:
|
`ADD:
|
begin
|
begin
|
q8 = add8_r;
|
q8 = add8_r;
|
c8 = cadd8_r;
|
c8 = cadd8_r;
|
v8 = vadd8_r;
|
v8 = vadd8_r;
|
q16 = add16_r;
|
|
c16 = cadd16_r;
|
|
v16 = vadd16_r;
|
|
end
|
end
|
`ADC:
|
`ADC:
|
begin
|
begin
|
q8 = adc8_r;
|
q8 = adc8_r;
|
c8 = cadc8_r;
|
c8 = cadc8_r;
|
v8 = vadc8_r;
|
v8 = vadc8_r;
|
q16 = adc16_r;
|
|
c16 = cadc16_r;
|
|
v16 = vadc16_r;
|
|
end
|
end
|
`CMP, `SUB: // for CMP no register result is written back
|
`CMP, `SUB: // for CMP no register result is written back
|
begin
|
begin
|
q8 = sub8_r;
|
q8 = sub8_r;
|
c8 = csub8_r;
|
c8 = csub8_r;
|
v8 = vsub8_r;
|
v8 = vsub8_r;
|
q16 = sub16_r;
|
|
c16 = csub16_r;
|
|
v16 = vsub16_r;
|
|
end
|
end
|
`SBC:
|
`SBC:
|
begin
|
begin
|
q8 = sbc8_r;
|
q8 = sbc8_r;
|
c8 = csbc8_r;
|
c8 = csbc8_r;
|
v8 = vsbc8_r;
|
v8 = vsbc8_r;
|
q16 = sbc16_r;
|
|
c16 = csbc16_r;
|
|
v16 = vsbc16_r;
|
|
end
|
end
|
`COM:
|
`COM:
|
begin
|
begin
|
q8 = com8_r;
|
q8 = com8_r;
|
c8 = com8_r;
|
c8 = com8_r;
|
v8 = vcom8_r;
|
v8 = vcom8_r;
|
q16 = com16_r;
|
|
c16 = ccom16_r;
|
|
v16 = vcom16_r;
|
|
end
|
end
|
`NEG:
|
`NEG:
|
begin
|
begin
|
q8 = neg8_r;
|
q8 = neg8_r;
|
c8 = cneg8_r;
|
c8 = cneg8_r;
|
v8 = vneg8_r;
|
v8 = vneg8_r;
|
q16 = neg16_r;
|
|
c16 = cneg16_r;
|
|
v16 = vneg16_r;
|
|
end
|
end
|
`ASR:
|
`ASR:
|
begin
|
begin
|
q8 = asr8_r;
|
q8 = asr8_r;
|
c8 = casr8_r;
|
c8 = casr8_r;
|
v8 = vasr8_r;
|
v8 = vasr8_r;
|
q16 = asr16_r;
|
|
c16 = casr16_r;
|
|
v16 = vasr16_r;
|
|
end
|
end
|
`LSR:
|
`LSR:
|
begin
|
begin
|
q8 = shr8_r;
|
q8 = shr8_r;
|
c8 = cshr8_r;
|
c8 = cshr8_r;
|
v8 = vshr8_r;
|
v8 = vshr8_r;
|
q16 = shr16_r;
|
|
c16 = cshr16_r;
|
|
v16 = vshr16_r;
|
|
end
|
end
|
`LSL:
|
`LSL:
|
begin
|
begin
|
q8 = shl8_r;
|
q8 = shl8_r;
|
c8 = cshl8_r;
|
c8 = cshl8_r;
|
v8 = vshl8_r;
|
v8 = vshl8_r;
|
q16 = shl16_r;
|
|
c16 = cshl16_r;
|
|
v16 = vshl16_r;
|
|
end
|
end
|
`ROR:
|
`ROR:
|
begin
|
begin
|
q8 = ror8_r;
|
q8 = ror8_r;
|
c8 = cror8_r;
|
c8 = cror8_r;
|
v8 = vror8_r;
|
v8 = vror8_r;
|
q16 = ror16_r;
|
|
c16 = cror16_r;
|
|
v16 = vror16_r;
|
|
end
|
end
|
`ROL:
|
`ROL:
|
begin
|
begin
|
q8 = rol8_r;
|
q8 = rol8_r;
|
c8 = crol8_r;
|
c8 = crol8_r;
|
v8 = vrol8_r;
|
v8 = vrol8_r;
|
q16 = rol16_r;
|
|
c16 = crol16_r;
|
|
v16 = vrol16_r;
|
|
end
|
end
|
`AND:
|
`AND:
|
begin
|
begin
|
q8 = and8_r;
|
q8 = and8_r;
|
c8 = cand8_r;
|
c8 = cand8_r;
|
v8 = vand8_r;
|
v8 = vand8_r;
|
`ifdef HD6309
|
|
q16 = and16_r;
|
|
c16 = cand16_r;
|
|
v16 = vand16_r;
|
|
`endif
|
|
end
|
end
|
`OR:
|
`OR:
|
begin
|
begin
|
q8 = or8_r;
|
q8 = or8_r;
|
c8 = cand8_r;
|
c8 = cand8_r;
|
v8 = vand8_r;
|
v8 = vand8_r;
|
`ifdef HD6309
|
|
q16 = or16_r;
|
|
c16 = cand16_r;
|
|
v16 = vand16_r;
|
|
`endif
|
|
end
|
end
|
`EOR:
|
`EOR:
|
begin
|
begin
|
q8 = eor8_r;
|
q8 = eor8_r;
|
c8 = cand8_r;
|
c8 = cand8_r;
|
v8 = vand8_r;
|
v8 = vand8_r;
|
`ifdef HD6309
|
|
q16 = eor16_r;
|
|
c16 = cand16_r;
|
|
v16 = vand16_r;
|
|
`endif
|
|
end
|
end
|
`DAA:
|
`DAA:
|
begin // V is undefined, so we don't touch it
|
begin // V is undefined, so we don't touch it
|
q8 = { daa8h_r, daa8l_r };
|
q8 = { daa8h_r, daa8l_r };
|
c8 = cdaa8_r;
|
c8 = cdaa8_r;
|
end
|
end
|
`MUL:
|
`MUL:
|
begin
|
begin
|
q16 = mul16_r;
|
|
c16 = cmul16_r;
|
|
end
|
end
|
`LD:
|
`LD:
|
begin
|
begin
|
v8 = 0;
|
v8 = 0;
|
v16 = 0;
|
|
q8 = b_in[7:0];
|
q8 = b_in[7:0];
|
q16 = b_in[15:0];
|
|
end
|
end
|
`ST:
|
`ST:
|
begin
|
begin
|
q8 = a_in[7:0];
|
q8 = a_in[7:0];
|
q16 = a_in[15:0];
|
|
end
|
end
|
`T816: // zero extend 8 -> 16
|
endcase
|
|
end
|
|
|
|
reg [7:0] regq8;
|
|
/* register before second mux */
|
|
always @(posedge clk_in)
|
begin
|
begin
|
q16 = { 8'h0, b_in[7:0] };
|
regq8 <= q8;
|
end
|
end
|
`T168L: // 16L -> 8
|
|
|
always @(*)
|
begin
|
begin
|
q8 = b_in[7:0];
|
q_out[7:0] = q8; //regq8;
|
|
case (opcode_in)
|
|
`ORCC:
|
|
CCRo = CCR | b_in[7:0];
|
|
`ANDCC:
|
|
CCRo = CCR & b_in[7:0];
|
|
default:
|
|
CCRo = { CCR[7:6], CCR[5], h8, q8[7], (q8 == 8'h0), v8, c8 };
|
|
endcase
|
end
|
end
|
`T168H: // 16L -> 8
|
|
|
initial
|
begin
|
begin
|
q8 = b_in[15:8];
|
end
|
|
endmodule
|
|
|
|
/* ALU for 16 bit operations */
|
|
module alu16(
|
|
input wire clk_in,
|
|
input wire [15:0] a_in,
|
|
input wire [15:0] b_in,
|
|
input wire [7:0] CCR, /* condition code register */
|
|
input wire [4:0] opcode_in, /* ALU opcode */
|
|
output reg [15:0] q_out, /* ALU result */
|
|
output reg [3:0] CCRo
|
|
);
|
|
|
|
wire c_in, n_in, v_in, z_in;
|
|
assign c_in = CCR[0]; /* carry flag */
|
|
assign n_in = CCR[3]; /* neg flag */
|
|
assign v_in = CCR[1]; /* overflow flag */
|
|
assign z_in = CCR[2]; /* zero flag */
|
|
|
|
wire [15:0] add16_r, adc16_r, sub16_r, sbc16_r, com16_r, neg16_r;
|
|
wire [15:0] asr16_r, shr16_r, shl16_r, ror16_r, rol16_r, and16_r, or16_r, eor16_r, mul16_r;
|
|
|
|
wire [15:0] add16_w, adc16_w, com16_w, neg16_w, sub16_w, sbc16_w;
|
|
wire [15:0] asr16_w, shr16_w, shl16_w, ror16_w, rol16_w, and16_w, or16_w, eor16_w;
|
|
|
|
wire cadd16_w, cadc16_w, csub16_w, csbc16_w;
|
|
|
|
wire cadd16_r, cadc16_r, csub16_r, csbc16_r, ccom16_r, cneg16_r;
|
|
wire casr16_r, cshr16_r, cshl16_r, cror16_r, crol16_r, cand16_r, cmul16_r;
|
|
|
|
wire vadd16_r, vadc16_r, vsub16_r, vsbc16_r, vcom16_r, vneg16_r;
|
|
wire vasr16_r, vshr16_r, vshl16_r, vror16_r, vrol16_r, vand16_r;
|
|
|
|
|
|
assign { cadd16_w, add16_w } = { 1'b0, a_in[15:0] } + { 1'b0, b_in[15:0] };
|
|
|
|
assign { cadc16_w, adc16_w } = { 1'b0, a_in[15:0] } + { 1'b0, b_in[15:0] } + { 16'h0, c_in };
|
|
|
|
|
|
assign { csub16_w, sub16_w } = { 1'b0, a_in[15:0] } - { 1'b0, b_in[15:0] };
|
|
|
|
assign { csbc16_w, sbc16_w } = { 1'b0, a_in[15:0] } - { 1'b0, b_in[15:0] } - { 16'h0, c_in };
|
|
|
|
|
|
assign com16_w = ~a_in[15:0];
|
|
|
|
assign neg16_w = 16'h0 - a_in[15:0];
|
|
|
|
assign asr16_w = { a_in[15], a_in[15:1] };
|
|
|
|
assign shr16_w = { 1'b0, a_in[15:1] };
|
|
|
|
assign shl16_w = { a_in[14:0], 1'b0 };
|
|
|
|
assign ror16_w = { c_in, a_in[15:1] };
|
|
|
|
assign rol16_w = { a_in[14:0], c_in };
|
|
|
|
assign and16_w = a_in[15:0] & b_in[15:0];
|
|
|
|
assign or16_w = a_in[15:0] | b_in[15:0];
|
|
|
|
assign eor16_w = a_in[15:0] ^ b_in[15:0];
|
|
|
|
// ADD, ADC
|
|
assign { cadd16_r, add16_r } = { cadd16_w, add16_w };
|
|
assign vadd16_r = (a_in[15] & b_in[15] & (~add16_w[15])) | ((~a_in[15]) & (~b_in[15]) & add16_w[15]);
|
|
assign { cadc16_r, adc16_r } = { cadd16_w, add16_w };
|
|
assign vadc16_r = (a_in[15] & b_in[15] & (~add16_w[15])) | ((~a_in[15]) & (~b_in[15]) & adc16_w[15]);
|
|
// SUB, SUBC
|
|
assign { csub16_r, sub16_r } = { csub16_w, sub16_w };
|
|
assign vsub16_r = (a_in[15] & b_in[15] & (~add16_w[15])) | ((~a_in[15]) & b_in[15] & sub16_w[15]);
|
|
assign { csbc16_r, sbc16_r } = { csbc16_w, sbc16_w };
|
|
assign vsbc16_r = (a_in[15] & b_in[15] & (~sbc16_w[15])) | ((~a_in[15]) & b_in[15] & sbc16_w[15]);
|
|
// COM
|
|
assign com16_r = com16_w;
|
|
assign ccom16_r = com16_w != 16'h0 ? 1'b1:1'b0;
|
|
assign vcom16_r = 1'b0;
|
|
// NEG
|
|
assign neg16_r = neg16_w;
|
|
assign vneg16_r = neg16_w[15] & (~neg16_w[14]) & (~neg16_w[13]) & (~neg16_w[12]) & (~neg16_w[11]) & (~neg16_w[10]) & (~neg16_w[9]) & (~neg16_w[8]) & (~neg16_w[7]) & (~neg16_w[6]) & (~neg16_w[5]) & (~neg16_w[4]) & (~neg16_w[3]) & (~neg16_w[2]) & (~neg16_w[1]) & (~neg16_w[0]);
|
|
assign cneg16_r = neg16_w[15] | neg16_w[14] | neg16_w[13] | neg16_w[12] | neg16_w[11] | neg16_w[10] | neg16_w[9] & neg16_w[8] | neg16_w[7] | neg16_w[6] | neg16_w[5] | neg16_w[4] | neg16_w[3] | neg16_w[2] | neg16_w[1] | neg16_w[0];
|
|
// ASR
|
|
assign asr16_r = asr16_w;
|
|
assign casr16_r = a_in[0];
|
|
assign vasr16_r = a_in[0] ^ asr16_w[15];
|
|
// SHR
|
|
assign shr16_r = shr16_w;
|
|
assign cshr16_r = a_in[0];
|
|
assign vshr16_r = a_in[0] ^ shr16_w[15];
|
|
// SHL
|
|
assign shl16_r = shl16_w;
|
|
assign cshl16_r = a_in[15];
|
|
assign vshl16_r = a_in[15] ^ shl16_w[15];
|
|
// ROR
|
|
assign ror16_r = ror16_w;
|
|
assign cror16_r = a_in[0];
|
|
assign vror16_r = a_in[0] ^ ror16_w[15];
|
|
// ROL
|
|
assign rol16_r = rol16_w;
|
|
assign crol16_r = a_in[15];
|
|
assign vrol16_r = a_in[15] ^ rol16_w[15];
|
|
// AND
|
|
assign and16_r = and16_w;
|
|
assign cand16_r = c_in;
|
|
assign vand16_r = 1'b0;
|
|
// OR
|
|
assign or16_r = or16_w;
|
|
// EOR
|
|
assign eor16_r = eor16_w;
|
|
|
|
wire [15:0] q16_mul;
|
|
|
|
mul8x8 mulu(clk_in, a_in[7:0], b_in[7:0], mul16_r);
|
|
assign cmul16_r = mul16_r[7];
|
|
|
|
reg c16, n16, v16, z16;
|
|
reg [15:0] q16;
|
|
|
|
always @(*)
|
|
begin
|
|
q16 = 16'h0;
|
|
c16 = c_in;
|
|
v16 = v_in;
|
|
case (opcode_in)
|
|
`ADD:
|
|
begin
|
|
q16 = add16_r;
|
|
c16 = cadd16_r;
|
|
v16 = vadd16_r;
|
|
end
|
|
`ADC:
|
|
begin
|
|
q16 = adc16_r;
|
|
c16 = cadc16_r;
|
|
v16 = vadc16_r;
|
|
end
|
|
`CMP, `SUB: // for CMP no register result is written back
|
|
begin
|
|
q16 = sub16_r;
|
|
c16 = csub16_r;
|
|
v16 = vsub16_r;
|
|
end
|
|
`SBC:
|
|
begin
|
|
q16 = sbc16_r;
|
|
c16 = csbc16_r;
|
|
v16 = vsbc16_r;
|
|
end
|
|
`ifdef HD6309
|
|
`COM:
|
|
begin
|
|
q16 = com16_r;
|
|
c16 = ccom16_r;
|
|
v16 = vcom16_r;
|
|
end
|
|
`NEG:
|
|
begin
|
|
q16 = neg16_r;
|
|
c16 = cneg16_r;
|
|
v16 = vneg16_r;
|
|
end
|
|
`ASR:
|
|
begin
|
|
q16 = asr16_r;
|
|
c16 = casr16_r;
|
|
v16 = vasr16_r;
|
|
end
|
|
`LSR:
|
|
begin
|
|
q16 = shr16_r;
|
|
c16 = cshr16_r;
|
|
v16 = vshr16_r;
|
|
end
|
|
`LSL:
|
|
begin
|
|
q16 = shl16_r;
|
|
c16 = cshl16_r;
|
|
v16 = vshl16_r;
|
|
end
|
|
`ROR:
|
|
begin
|
|
q16 = ror16_r;
|
|
c16 = cror16_r;
|
|
v16 = vror16_r;
|
|
end
|
|
`ROL:
|
|
begin
|
|
q16 = rol16_r;
|
|
c16 = crol16_r;
|
|
v16 = vrol16_r;
|
|
end
|
|
`AND:
|
|
begin
|
|
q16 = and16_r;
|
|
c16 = cand16_r;
|
|
v16 = vand16_r;
|
|
end
|
|
`OR:
|
|
begin
|
|
q16 = or16_r;
|
|
c16 = cand16_r;
|
|
v16 = vand16_r;
|
|
end
|
|
`EOR:
|
|
begin
|
|
q16 = eor16_r;
|
|
c16 = cand16_r;
|
|
v16 = vand16_r;
|
|
end
|
|
`endif
|
|
`MUL:
|
|
begin
|
|
q16 = mul16_r;
|
|
c16 = cmul16_r;
|
|
end
|
|
`LD:
|
|
begin
|
|
v16 = 0;
|
|
q16 = b_in[15:0];
|
|
end
|
|
`ST:
|
|
begin
|
|
q16 = a_in[15:0];
|
end
|
end
|
`SEXT: // sign extend
|
`SEXT: // sign extend
|
begin
|
begin
|
q16 = { b_in[7] ? 8'hff:8'h00, b_in[7:0] };
|
q16 = { b_in[7] ? 8'hff:8'h00, b_in[7:0] };
|
end
|
end
|
Line 371... |
Line 553... |
q16 = a_in[15:0];
|
q16 = a_in[15:0];
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
|
|
reg [7:0] regq8;
|
|
reg [15:0] regq16;
|
reg [15:0] regq16;
|
reg reg_n_in, reg_z_in;
|
reg reg_n_in, reg_z_in;
|
/* register before second mux */
|
/* register before second mux */
|
always @(posedge clk)
|
always @(posedge clk_in)
|
begin
|
begin
|
regq8 <= q8;
|
|
regq16 <= q16;
|
regq16 <= q16;
|
reg_n_in <= n_in;
|
reg_n_in <= n_in;
|
reg_z_in <= z_in;
|
reg_z_in <= z_in;
|
end
|
end
|
|
|
/* Negative & zero flags */
|
/* Negative & zero flags */
|
always @(*)
|
always @(*)
|
begin
|
begin
|
n8 = regq8[7];
|
n16 = q16[15];
|
z8 = regq8 == 8'h0;
|
z16 = q16 == 16'h0;
|
n16 = regq16[15];
|
|
z16 = regq16 == 16'h0;
|
|
case (opcode_in)
|
case (opcode_in)
|
`ADD:
|
`ADD:
|
begin
|
begin
|
end
|
end
|
`ADC:
|
`ADC:
|
Line 433... |
Line 611... |
begin
|
begin
|
end
|
end
|
`EOR:
|
`EOR:
|
begin
|
begin
|
end
|
end
|
`DAA:
|
|
begin // V is undefined, so we don't touch it
|
|
end
|
|
`MUL:
|
`MUL:
|
begin
|
begin
|
n16 = reg_n_in;
|
n16 = reg_n_in;
|
z16 = reg_z_in;
|
|
end
|
end
|
`LD:
|
`LD:
|
begin
|
begin
|
end
|
end
|
`ST:
|
`ST:
|
begin
|
begin
|
end
|
end
|
`T816: // zero extend 8 -> 16
|
|
begin
|
|
n16 = reg_n_in;
|
|
z16 = reg_z_in;
|
|
end
|
|
`T168L: // 16L -> 8
|
|
begin
|
|
n8 = reg_n_in;
|
|
z8 = reg_z_in;
|
|
end
|
|
`T168H: // 16L -> 8
|
|
begin
|
|
n8 = reg_n_in;
|
|
z8 = reg_z_in;
|
|
end
|
|
`SEXT: // sign extend
|
`SEXT: // sign extend
|
begin
|
begin
|
n16 = reg_n_in;
|
n16 = reg_n_in;
|
z16 = reg_z_in;
|
z16 = reg_z_in;
|
end
|
end
|
Line 477... |
Line 636... |
end
|
end
|
|
|
|
|
always @(*)
|
always @(*)
|
begin
|
begin
|
q_out[15:8] = regq16[15:8];
|
q_out = q16;
|
if (sz_in)
|
CCRo = { n16, z16, v16, c16 };
|
q_out[7:0] = regq16[7:0];
|
|
else
|
|
q_out[7:0] = regq8;
|
|
case (opcode_in)
|
|
`ORCC:
|
|
CCRo = CCR | b_in[7:0];
|
|
`ANDCC:
|
|
CCRo = CCR & b_in[7:0];
|
|
default:
|
|
if (sz_in) // 16 bit
|
|
CCRo = { CCR[7:4], n16, z16, v16, c16 };
|
|
else
|
|
CCRo = { CCR[7:6], CCR[5], h8, n8, z8, v8, c8 };
|
|
endcase
|
|
end
|
end
|
|
|
initial
|
initial
|
begin
|
begin
|
end
|
end
|
endmodule
|
endmodule
|
|
|
module mul8x8(
|
module mul8x8(
|
input wire clk,
|
input wire clk_in,
|
input wire [7:0] a,
|
input wire [7:0] a,
|
input wire [7:0] b,
|
input wire [7:0] b,
|
output wire [15:0] q
|
output wire [15:0] q
|
);
|
);
|
|
|
always @(posedge clk)
|
reg [15:0] pipe0, pipe1;//, pipe2, pipe3;
|
begin
|
assign q = pipe1;
|
|
|
ebd
|
always @(posedge clk_in)
|
|
begin
|
|
pipe0 <= (a[0] ? {8'h0, b}:16'h0) + (a[1] ? { 7'h0, b, 1'h0}:16'h0) +
|
|
(a[2] ? {6'h0, b, 2'h0}:16'h0) + (a[3] ? { 5'h0, b, 3'h0}:16'h0);
|
|
pipe1 <= (a[4] ? {4'h0, b, 4'h0}:16'h0) + (a[5] ? { 3'h0, b, 5'h0}:16'h0) +
|
|
(a[6] ? {2'h0, b, 6'h0}:16'h0) + (a[7] ? { 1'h0, b, 7'h0}:16'h0) + pipe0;
|
|
/*
|
|
pipe0 <= (a[0] ? {8'h0, b}:16'h0) + (a[1] ? { 7'h0, b, 1'h0}:16'h0);
|
|
pipe1 <= (a[2] ? {6'h0, b, 2'h0}:16'h0) + (a[3] ? { 5'h0, b, 3'h0}:16'h0) + pipe0;
|
|
pipe2 <= (a[4] ? {4'h0, b, 4'h0}:16'h0) + (a[5] ? { 3'h0, b, 5'h0}:16'h0) + pipe1;
|
|
pipe3 <= (a[6] ? {2'h0, b, 6'h0}:16'h0) + (a[7] ? { 1'h0, b, 7'h0}:16'h0) + pipe2;
|
|
*/
|
|
end
|
|
|
endmodule
|
endmodule
|
No newline at end of file
|
No newline at end of file
|