URL
https://opencores.org/ocsvn/rtf8088/rtf8088/trunk
Subversion Repositories rtf8088
Compare Revisions
- This comparison shows the changes necessary to convert path
/rtf8088
- from Rev 5 to Rev 6
- ↔ Reverse comparison
Rev 5 → Rev 6
/trunk/rtl/verilog/ALU.v
62,6 → 62,8
wire signed [7:0] bls = b[7:0]; |
wire signed [15:0] p = als * bls; |
wire signed [31:0] wp = sa * sb; |
wire [15:0] p16 = a[7:0] * b[7:0]; |
wire [31:0] p32 = a * b; |
|
// Compute AL/10 |
// - multiply by 1/10 = 26/256 |
85,7 → 87,50
wire [16:0] shlco8 = {8'h00,b,cf} << shftamt; |
wire [16:0] shrcuo8 = {cf,b[7:0],8'h00} >> shftamt; |
|
wire div16_done; |
wire div32_done; |
wire [15:0] q16; |
wire [7:0] r16; |
wire [31:0] q32; |
wire [15:0] r32; |
wire [31:0] negdxax = -{dx,ax}; |
|
divr2 #(16) udiv1 |
( |
.rst(rst_i), |
.clk(clk_i), |
.ce(1'b1), |
.ld(ld_div16), |
.su(TTT[0]), |
.ri(1'b0), |
.a(ax), |
.b(b[7:0]), |
.i(8'h00), |
.q(q16), |
.r(r16), |
.divByZero(), |
.done(div16_done) |
); |
|
|
divr2 #(32) udiv2 |
( |
.rst(rst_i), |
.clk(clk_i), |
.ce(1'b1), |
.ld(ld_div32), |
.su(TTT[0]), |
.ri(1'b0), |
.a({dx,ax}), |
.b(b), |
.i(16'h0000), |
.q(q32), |
.r(r32), |
.divByZero(), |
.done(div32_done) |
); |
|
|
always @(ir or ir2 or a or b or cf or af or al or ah or aldv10 or TTT) |
begin |
casex(ir) |
104,6 → 149,7
`ADC,`ADC_ALI8,`ADC_AXI16: alu_o <= a + b + cf; |
`SBB,`SBB_ALI8,`SBB_AXI16: alu_o <= a - b - cf; |
`AND,`AND_ALI8,`AND_AXI16: alu_o <= a & b; |
`TEST,`TEST_ALI8,`TEST_AXI16: alu_o <= a & b; |
`OR, `OR_ALI8, `OR_AXI16: alu_o <= a | b; |
`XOR,`XOR_ALI8,`XOR_AXI16: alu_o <= a ^ b; |
`CMP,`CMP_ALI8,`CMP_AXI16: alu_o <= a - b; |
134,6 → 180,17
3'd6: alu_o <= a ^ b; // XOR |
default: alu_o <= 16'h0000; |
endcase |
8'hF6,8'hF7: |
case(TTT) |
3'd0: alu_o <= a & b; // TEST |
3'd2: alu_o <= ~b; // NOT |
3'd3: alu_o <= -b; // NEG |
3'd4: alu_o <= w ? p32[15:0] : p16; // MUL |
3'd5: alu_o <= w ? wp[15:0] : p[15:0]; // IMUL |
3'd6: alu_o <= 16'h0000; // DIV |
3'd7: alu_o <= 16'h0000; // IDIV |
default: alu_o <= 16'h0000; |
endcase |
`AAA: |
if (al[3:0]>4'h9 || af) begin |
alu_o[3:0] <= al[3:0] + 4'd6; |
/trunk/rtl/verilog/rtf8088.v
27,7 → 27,7
// 650 ff's / 2 MULTs |
// |
// Webpack 14.3 xc6slx45 3-csg324 |
// 736 ff's 4433 LUTs / 90.360 MHz |
// 884 ff's 5064 LUTs / 79.788 MHz |
// ============================================================================ |
|
//`define BYTES_ONLY 1'b1 |
210,6 → 210,8
`define MOVSW 8'hA5 |
`define CMPSB 8'hA6 |
`define CMPSW 8'hA7 |
`define TEST_ALI8 8'hA8 |
`define TEST_AXI16 8'hA9 |
`define STOSB 8'hAA |
`define STOSW 8'hAB |
`define LODSB 8'hAC |
343,9 → 345,9
010 = NOT |
011 = NEG |
100 = MUL |
101 = |
110 = |
111 = |
101 = IMUL |
110 = DIV |
111 = IDIV |
*/ |
`define ADDRESS_INACTIVE 20'hFFFFF |
`define DATA_INACTIVE 8'hFF |
576,6 → 578,12
parameter CALL_FIN3 = 8'd213; |
parameter CALL_FIN4 = 8'd214; |
|
parameter DIVIDE1 = 8'd215; |
parameter DIVIDE1a = 8'd216; |
parameter DIVIDE2 = 8'd217; |
parameter DIVIDE2a = 8'd218; |
parameter DIVIDE3 = 8'd219; |
|
parameter INT = 8'd220; |
parameter INT1 = 8'd221; |
parameter INT2 = 8'd222; |
690,6 → 698,8
reg wrsregs; |
wire take_br; |
reg [3:0] shftamt; |
reg ld_div16,ld_div32; // load divider |
reg div_sign; |
|
reg nmi_armed; |
reg rst_nmi; // reset the nmi flag |
703,7 → 713,7
`include "CONTROL_LOGIC.v" |
`include "which_seg.v" |
evaluate_branch u4 (ir,cx,zf,cf,sf,vf,pf,take_br); |
`include "ALU.v" |
`include "c:\cores\bcxa6\rtl\verilog\eight_bit\ALU.v" |
nmi_detector u6 (RESET, CLK, NMI, rst_nmi, pe_nmi); |
|
always @(posedge CLK) |
730,6 → 740,8
rst_nmi <= 1'b1; |
wrregs <= 1'b0; |
wrsregs <= 1'b0; |
ld_div16 <= 1'b0; |
ld_div32 <= 1'b0; |
state <= IFETCH; |
end |
else begin |
736,6 → 748,8
rst_nmi <= 1'b0; |
wrregs <= 1'b0; |
wrsregs <= 1'b0; |
ld_div16 <= 1'b0; |
ld_div32 <= 1'b0; |
|
`include "WRITE_BACK.v" |
|
781,6 → 795,7
`include "INSB.v" |
`include "OUTSB.v" |
`include "XCHG_MEM.v" |
`include "DIVIDE.v" |
|
default: |
state <= IFETCH; |
/trunk/rtl/verilog/EXECUTE.v
100,13 → 100,70
|
8'hF6,8'hF7: |
begin |
wrregs <= 1'b1; |
state <= IFETCH; |
case(rrr) |
3'd2: res <= ~b; // NOT |
3'd3: res <= -b; // NEG |
res <= alu_o; |
case(TTT) |
3'd0: // TEST |
begin |
pf <= pres; |
cf <= 1'b0; |
vf <= 1'b0; |
sf <= resn; |
zf <= resz; |
end |
3'd2: // NOT |
begin |
wrregs <= 1'b1; |
end |
3'd3: // NEG |
begin |
pf <= pres; |
af <= carry (1'b1,1'b0,b[3],alu_o[3]); |
cf <= carry (1'b1,1'b0,bmsb,resn); |
vf <= overflow(1'b1,1'b0,bmsb,resn); |
sf <= resn; |
zf <= resz; |
wrregs <= 1'b1; |
end |
// Normally only a single register update is required, however with |
// multiply word both AX and DX need to be updated. So we bypass the |
// regular update here. |
3'd4: |
begin |
if (w) begin |
ax <= p32[15:0]; |
dx <= p32[31:16]; |
cf <= p32[31:16]!=16'd0; |
vf <= p32[31:16]!=16'd0; |
end |
else begin |
ax <= p16; |
cf <= p16[15:8]!=8'd0; |
vf <= p16[15:8]!=8'd0; |
end |
end |
3'd5: |
begin |
if (w) begin |
ax <= wp[15:0]; |
dx <= wp[31:16]; |
cf <= p32[31:16]!=16'd0; |
vf <= p32[31:16]!=16'd0; |
end |
else begin |
ax <= p; |
cf <= p[15:8]!=8'd0; |
vf <= p[15:8]!=8'd0; |
end |
end |
3'd6,3'd7: |
begin |
state <= DIVIDE1; |
end |
default: ; |
endcase |
end |
|
`INC_REG: |
begin |
state <= IFETCH; |
282,7 → 339,6
end |
3'b100: // SHL |
begin |
$display("SHL:%h,%h,%d",shlo[15:0],b,shftamt); |
res <= shlo[15:0]; |
cf <= shlo[16]; |
vf <= b[15]^b[14]; |
289,7 → 345,6
end |
3'b101: // SHR |
begin |
$display("SHR:%h,%h,%d",shruo[31:16],b,shftamt); |
res <= shruo[31:16]; |
cf <= shruo[15]; |
vf <= b[15]; |
/trunk/rtl/verilog/DIVIDE.v
0,0 → 1,101
//============================================================================ |
// DIVIDE.v |
// |
// (C) 2009-2012 Robert Finch |
// Stratford |
// robfinch<remove>@opencores.org |
// |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// |
//============================================================================= |
// |
// Check for divide by zero |
// Load the divider |
DIVIDE1: |
begin |
state <= DIVIDE2; |
// Check for divide by zero |
if (w) begin |
if (b[15:0]==16'h0000) begin |
$display("Divide by zero"); |
int_num <= 8'h00; |
state <= INT2; |
end |
else |
ld_div32 <= 1'b1; |
end |
else begin |
if (b[7:0]==8'h00) begin |
$display("Divide by zero"); |
int_num <= 8'h00; |
state <= INT2; |
end |
else |
ld_div16 <= 1'b1; |
end |
end |
DIVIDE2: |
begin |
ld_div32 <= 1'b0; |
ld_div16 <= 1'b0; |
state <= DIVIDE2a; |
end |
DIVIDE2a: |
begin |
if (w & div32_done) |
state <= DIVIDE3; |
else if (!w & div16_done) |
state <= DIVIDE3; |
end |
|
// Assign results to registers |
// Trap on divider overflow |
DIVIDE3: |
begin |
state <= IFETCH; |
if (w) begin |
ax <= q32[15:0]; |
dx <= r32[15:0]; |
if (TTT[0]) begin |
if (q32[31:16]!={16{q32[15]}}) begin |
int_num <= 8'h00; |
state <= INT2; |
end |
end |
else begin |
if (q32[31:16]!=16'h0000) begin |
int_num <= 8'h00; |
state <= INT2; |
end |
end |
end |
else begin |
ax[ 7:0] <= q16[7:0]; |
ax[15:8] <= r16; |
if (TTT[0]) begin |
if (q16[15:8]!={8{q16[7]}}) begin |
int_num <= 8'h00; |
state <= INT2; |
end |
end |
else begin |
if (q16[15:8]!=8'h00) begin |
int_num <= 8'h00; |
state <= INT2; |
end |
end |
end |
end |
/trunk/rtl/verilog/DECODE.v
95,7 → 95,7
af <= (al[3:0]>4'h9 || af); |
cf <= (al[3:0]>4'h9 || af); |
end |
`ADD_ALI8,`ADC_ALI8,`SUB_ALI8,`SBB_ALI8,`AND_ALI8,`OR_ALI8,`XOR_ALI8,`CMP_ALI8: |
`ADD_ALI8,`ADC_ALI8,`SUB_ALI8,`SBB_ALI8,`AND_ALI8,`OR_ALI8,`XOR_ALI8,`CMP_ALI8,`TEST_ALI8: |
begin |
w <= 1'b0; |
a <= {{8{al[7]}},al}; |
102,7 → 102,7
rrr <= 3'd0; |
state <= FETCH_IMM8; |
end |
`ADD_AXI16,`ADC_AXI16,`SUB_AXI16,`SBB_AXI16,`AND_AXI16,`OR_AXI16,`XOR_AXI16,`CMP_AXI16: |
`ADD_AXI16,`ADC_AXI16,`SUB_AXI16,`SBB_AXI16,`AND_AXI16,`OR_AXI16,`XOR_AXI16,`CMP_AXI16,`TEST_AXI16: |
begin |
w <= 1'b1; |
a <= ax; |
278,7 → 278,7
//----------------------------------------------------------------- |
// MOD/RM instructions |
//----------------------------------------------------------------- |
$display("Fetching mod/rm"); |
$display("Fetching mod/rm, w=",w); |
if (ir==`MOV_R2S || ir==`MOV_S2R) |
w <= 1'b1; |
if (ir==`LDS || ir==`LES) |
/trunk/rtl/verilog/EACALC.v
139,6 → 139,8
begin |
b <= rmo; |
end |
8'hF6,8'hF7: |
b <= rmo; |
default: |
begin |
if (d) begin |