⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 a86_alu.v

📁 intel 8088 架构的verilog代码
💻 V
字号:
// http://gforge.openchip.org/projects/a86

`include "timescale.v"
`include "a86_defines.v"

`include "a86_ADSU16_XILINX.v"
`include "a86_ADSU16_GENERIC.v"


module a86_alu(
  icode,
  ain,bin,
  dout,
  fin,fout,
  aluop,dout_hi
  );

  input [`a86_icode_width-1:0] icode;

input [15:0] ain;
input [15:0] bin;
output [15:0] dout;
output [15:0] dout_hi;

input [15:0] fin;
output [15:0] fout;
reg [15:0] fout;

input [7:0] aluop;

reg [15:0] dout;
reg [15:0] dout_hi;


//
reg [15:0] add_result;
reg [15:0] sub_result;

reg [15:0] and_result;
reg [15:0] or_result;
reg [15:0] xor_result;

reg [31:0] mul_result;
reg [15:0] alu_result;

//
reg [15:0] aaa_result;
reg [15:0] aad_result;
reg [15:0] aam_result;
reg [15:0] aas_result;


// AND gates
reg [15:0] sela_anded;
reg [15:0] selb_anded;
reg [15:0] add_anded;

reg [15:0] and_anded;
reg [15:0] or_anded;
reg [15:0] xor_anded;


// or together
reg [15:0] res_ored;



reg zf;
reg cf;

wire adsu_result;

// todo: Xilinx use ADDSU16, and carry chain for add and sub

`ifdef a86_vendor_xilinx

  a86_ADSU16_XILINX addsu16_0 (
    .A(ain), 
    .ADD(1'b0), 
    .B(bin), 
    .CI(fin[`psf_cf]), 
    .CO( ), 
    .OFL(), 
    .S(adsu_result)
    );

uu always @ (aluop,ain,bin,adsu_result) add_result <= adsu_result;
uuu always @ (aluop,ain,bin,adsu_result) sub_result <= adsu_result;


`endif

`ifdef a86_vendor_generic

//always @ (aluop,ain,bin) add_result = ain + bin + fin[`psf_cf];
//always @ (aluop,ain,bin) sub_result = ain - bin - fin[`psf_cf];

always @ (ain,bin) add_result = ain + bin;
always @ (ain,bin) sub_result = ain - bin;


`endif


// Logic Operations
always @ (ain,bin) or_result = ain | bin;
always @ (ain,bin) and_result = ain & bin;
always @ (ain,bin) xor_result = ain ^ bin;

// funny

always @ (aluop,ain) begin
/*
if (((AL = AL & 0x0F) > 9) || (AF == 1)) {
--   AL is not yet in BCD format note high nibble of AL is cleared either way) convert AL to decimal and unpack 
AL = (AL + 6) & 0x0F;
AH = AH + 1;
 set carry flags 
CF = AF = 1;
}
else
 --  clear carry flags 
CF = AF = 0;
*/

  aaa_result = {ain[15:8]+8'b00000001, (ain[7:0]+8'b00000110) & 8'b00001111 };
end

always @ (aluop,ain) begin
  aad_result = {8'b00000000, ain[15:8] * 8'b00001010 + ain[7:0]};
end

always @ (aluop,ain) begin
  //aam_result = {ain[7:0] / 10, ain[7:0] % 10};
  
  // TODO!
  aam_result = ain;
end

always @ (aluop,ain) begin

/*
if (((AL = AL & 0x0F) > 9) || (AF == 1)) {
  AL is not yet decimal (note high nibble of AL is cleared either way  convert AL to decimal and unpack 
AL = (AL - 6) & 0x0F;
AH = AH - 1;
 set carry flags 
CF = AF = 1;
}
else
 clear carry flags 
CF = AF = 0;
*/

  aas_result = {ain[15:8]-8'b00000001, (ain[7:0]-8'b00000110) & 8'b00001111 };

end


// XST uses embedded 18x18 multiply OK
always @ (aluop,ain,bin) mul_result = ain * bin;

/*
always @ (aluop)
  case(aluop[7:0])
    `alu_op_add: alu_result = add_result; // add, adc, inc
    `alu_op_sub: alu_result = sub_result; // sub, sbb, dec
    `alu_op_and: alu_result = and_result;
    `alu_op_or: alu_result = or_result;
    `alu_op_mul: alu_result = mul_result[15:0];
  
    8'b11110111: alu_result = fin; // bypass PSF reg for "PUSH Flags" :)
    default alu_result <= 16'h0000;
  endcase  
*/
  


// Muxin A
always @ (ain,icode) 
  if (icode[`a86_icode_alu_sela]) sela_anded = ain;
  else sela_anded = 16'h0000;

// Muxin B
always @ (bin,icode) 
  if (icode[`a86_icode_alu_selb]) selb_anded = bin;
  else selb_anded = 16'h0000;

// Muxin ADD result
always @ (add_result,icode) 
  if (icode[`a86_icode_incdec]) add_anded = add_result; 
  else add_anded = 16'h0000;

// Muxin AND result
always @ (and_result,icode) 
  if (icode[`a86_icode_alu_and]) and_anded = and_result; 
  else and_anded = 16'h0000;

// Muxin OR result
always @ (or_result,icode) 
  if (icode[`a86_icode_alu_or]) or_anded = or_result; 
  else or_anded = 16'h0000;

// Muxin XOR result
always @ (xor_result,icode) 
  if (icode[`a86_icode_alu_xor]) xor_anded = xor_result; 
  else xor_anded = 16'h0000;


// Muxin all in!
always @ (sela_anded,selb_anded,add_anded,and_anded,or_anded,xor_anded) 
  res_ored = 
     sela_anded | selb_anded 
   | add_anded 
   | and_anded | or_anded | xor_anded;


always @ (res_ored) dout = res_ored;


always @ (mul_result)
  dout_hi = mul_result[31:16];

reg aluop_is16;


// calculate out flags
reg f_parity_lo;
reg f_parity_hi;
reg f_parity;

reg f_zero_lo;
reg f_zero_hi;
reg f_zero;

// Zero Flag!
always @(dout) 
  f_zero_lo = dout[7:0] == 8'b00000000;

always @(dout) 
  f_zero_hi = dout[15:8] == 8'b00000000; //) & aluop_is16;

always @(f_zero_lo,f_zero_hi) 
  f_zero = f_zero_lo | f_zero_hi;


// send the flags out ...
always @(f_zero) 
  fout[`psf_zf] = f_zero;














endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -