OpenCores
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 6 to Rev 7
    Reverse comparison

Rev 6 → Rev 7

/trunk/rtl/verilog/rtf8088.v
802,4 → 802,6
endcase
end
 
`include "wb_task.v"
 
endmodule
/trunk/rtl/verilog/BRANCH.v
7,7 → 7,7
//
// (C) 2009-2012 Robert Finch
// Stratford
// robfinch<remove>@opencores.org
// robfinch<remove>@finitron.ca
//
//
// This source file is free software: you can redistribute it and/or modify
30,7 → 30,7
//
BRANCH1:
if (take_br) begin
`INITIATE_CODE_READ
code_read();
state <= BRANCH2;
end
else begin
39,7 → 39,7
end
BRANCH2:
if (ack_i) begin
`TERMINATE_CODE_READ
term_code_read();
disp16 <= {{8{dat_i[7]}},dat_i};
state <= BRANCH3;
end
/trunk/rtl/verilog/EXECUTE.v
158,6 → 158,7
end
3'd6,3'd7:
begin
$display("state <= DIVIDE1");
state <= DIVIDE1;
end
default: ;
/trunk/rtl/verilog/DIVIDE.v
49,6 → 49,7
end
DIVIDE2:
begin
$display("DIVIDE2");
ld_div32 <= 1'b0;
ld_div16 <= 1'b0;
state <= DIVIDE2a;
55,6 → 56,7
end
DIVIDE2a:
begin
$display("DIVIDE2a");
if (w & div32_done)
state <= DIVIDE3;
else if (!w & div16_done)
65,6 → 67,7
// Trap on divider overflow
DIVIDE3:
begin
$display("DIVIDE3 state <= IFETCH");
state <= IFETCH;
if (w) begin
ax <= q32[15:0];
71,6 → 74,7
dx <= r32[15:0];
if (TTT[0]) begin
if (q32[31:16]!={16{q32[15]}}) begin
$display("DIVIDE Overflow");
int_num <= 8'h00;
state <= INT2;
end
77,6 → 81,7
end
else begin
if (q32[31:16]!=16'h0000) begin
$display("DIVIDE Overflow");
int_num <= 8'h00;
state <= INT2;
end
87,6 → 92,7
ax[15:8] <= r16;
if (TTT[0]) begin
if (q16[15:8]!={8{q16[7]}}) begin
$display("DIVIDE Overflow");
int_num <= 8'h00;
state <= INT2;
end
93,6 → 99,7
end
else begin
if (q16[15:8]!=8'h00) begin
$display("DIVIDE Overflow");
int_num <= 8'h00;
state <= INT2;
end
/trunk/rtl/verilog/CMPSB.v
2,9 → 2,9
// CMPSB
//
//
// 2009-2012 Robert Finch
// 2009-2013 Robert Finch
// Stratford
// robfinch<remove>@opencores.org
// robfinch<remove>@finitron.ca
//
//
// This source file is free software: you can redistribute it and/or modify
24,20 → 24,15
//=============================================================================
//
CMPSB:
`include "check_for_ints.v"
else begin
cyc_type <= `CT_RDMEM;
begin
read(`CT_RDMEM,{seg_reg,`SEG_SHIFT} + si);
lock_o <= 1'b0;
cyc_o <= 1'b1;
stb_o <= 1'b1;
we_o <= 1'b0;
adr_o <= {seg_reg,`SEG_SHIFT} + si;
state <= CMPSB1;
end
CMPSB1:
if (ack_i) begin
nack();
state <= CMPSB2;
`TERMINATE_CYCLE
lock_o <= 1'b0;
a[ 7:0] <= dat_i[7:0];
a[15:8] <= {8{dat_i[7]}};
45,17 → 40,13
CMPSB2:
begin
state <= CMPSB3;
cyc_type <= `CT_RDMEM;
read(`CT_RDMEM,esdi);
lock_o <= 1'b0;
cyc_o <= 1'b1;
stb_o <= 1'b1;
we_o <= 1'b0;
adr_o <= esdi;
end
CMPSB3:
if (ack_i) begin
nack();
state <= CMPSB4;
`TERMINATE_CYCLE
lock_o <= 1'b0;
b[ 7:0] <= dat_i[7:0];
b[15:8] <= {8{dat_i[7]}};
78,7 → 69,8
end
if ((repz & !cxz & zf) | (repnz & !cxz & !zf)) begin
cx <= cx_dec;
state <= CMPSB;
ip <= ir_ip;
state <= IFETCH;
end
else
state <= IFETCH;
/trunk/rtl/verilog/CALL.v
2,9 → 2,9
// CALL NEAR
//
//
// 2009-2012 Robert Finch
// 2009-2013 Robert Finch
// Stratford
// robfinch<remove>@opencores.org
// robfinch<remove>@finitron.ca
//
//
// This source file is free software: you can redistribute it and/or modify
25,25 → 25,23
//
CALL:
begin
`INITIATE_STACK_WRITE
write(`CT_WRMEM,sssp,ip[15:8]);
lock_o <= 1'b1;
dat_o <= ip[15:8];
state <= CALL1;
end
CALL1:
if (ack_i) begin
state <= CALL2;
`PAUSE_STACK_WRITE
pause_stack_push();
end
CALL2:
begin
state <= CALL3;
`INITIATE_STACK_WRITE
dat_o <= ip[7:0];
write(`CT_WRMEM,sssp,ip[7:0]);
end
CALL3:
if (ack_i) begin
`TERMINATE_CYCLE
nack();
lock_o <= 1'b0;
ip <= ip + disp16;
state <= IFETCH;
/trunk/rtl/verilog/CALLF.v
2,9 → 2,9
// CALL FAR and CALL FAR indirect
//
//
// 2009-2012 Robert Finch
// 2009-2013 Robert Finch
// Stratford
// robfinch<remove>@opencores.org
// robfinch<remove>@finitron.ca
//
//
// This source file is free software: you can redistribute it and/or modify
25,47 → 25,43
//
CALLF:
begin
`INITIATE_STACK_WRITE
write(`CT_WRMEM,sssp,cs[15:8]);
lock_o <= 1'b1;
dat_o <= cs[15:8];
state <= CALLF1;
end
CALLF1:
if (ack_i) begin
`PAUSE_STACK_WRITE
pause_stack_push();
state <= CALLF2;
end
CALLF2:
begin
`INITIATE_STACK_WRITE
dat_o <= cs[7:0];
write(`CT_WRMEM,sssp,cs[7:0]);
state <= CALLF3;
end
CALLF3:
if (ack_i) begin
`PAUSE_STACK_WRITE
pause_stack_push();
state <= CALLF4;
end
CALLF4:
begin
`INITIATE_STACK_WRITE
dat_o <= ip[15:8];
write(`CT_WRMEM,sssp,ip[15:8]);
state <= CALLF5;
end
CALLF5:
if (ack_i) begin
`PAUSE_STACK_WRITE
pause_stack_push();
state <= CALLF6;
end
CALLF6:
begin
`INITIATE_STACK_WRITE
dat_o <= ip[7:0];
write(`CT_WRMEM,sssp,ip[7:0]);
state <= CALLF7;
end
CALLF7:
if (ack_i) begin
`TERMINATE_CYCLE
nack();
if (ir==8'hFF && rrr==3'b011) // CALL FAR indirect
state <= JUMP_VECTOR1;
else begin
/trunk/rtl/verilog/divr2.v
0,0 → 1,175
//=============================================================================
// (C) 2006,2011 Robert Finch
// robfinch@opencores.org
//
// divr2.v
// Radix 2 divider primitive
//
//
// This source code is available for evaluation and validation purposes
// only. This copyright statement and disclaimer must remain present in
// the file.
//
// NO WARRANTY.
// THIS Work, IS PROVIDEDED "AS IS" WITH NO WARRANTIES OF ANY KIND, WHETHER
// EXPRESS OR IMPLIED. The user must assume the entire risk of using the
// Work.
//
// IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
// INCIDENTAL, CONSEQUENTIAL, OR PUNITIVE DAMAGES WHATSOEVER RELATING TO
// THE USE OF THIS WORK, OR YOUR RELATIONSHIP WITH THE AUTHOR.
//
// IN ADDITION, IN NO EVENT DOES THE AUTHOR AUTHORIZE YOU TO USE THE WORK
// IN APPLICATIONS OR SYSTEMS WHERE THE WORK'S FAILURE TO PERFORM CAN
// REASONABLY BE EXPECTED TO RESULT IN A SIGNIFICANT PHYSICAL INJURY, OR IN
// LOSS OF LIFE. ANY SUCH USE BY YOU IS ENTIRELY AT YOUR OWN RISK, AND YOU
// AGREE TO HOLD THE AUTHOR AND CONTRIBUTORS HARMLESS FROM ANY CLAIMS OR
// LOSSES RELATING TO SUCH UNAUTHORIZED USE.
//
//
// Performance
// Webpack 9.2i xc3s1000-4ft256
// 64 slices / 122 LUTs / 17.316 ns (59 MHz)
//=============================================================================
 
module divr2(rst, clk, ce, ld, su, ri, a, b, i, q, r, divByZero, done);
parameter WID = 32;
parameter IDLE = 3'd0;
parameter DIV = 3'd1;
parameter SGN = 3'd2;
input rst;
input clk;
input ce; // clock enable
input ld; // pulse to initiate divide
input su; // 1=signed or 0=unsigned
input ri; // port: 1=register or 0=immediate
input [WID-1:0] a; // dividend
input [WID/2-1:0] b; // divisor: register port input
input [WID/2-1:0] i; // divisor: immediate value port input
output [WID-1:0] q; // quotient
output [WID/2-1:0] r; // remainder
output divByZero;
output done; // =1 if divide is finished
localparam DMSB = WID-1;
 
reg [7:0] cnt; // iteration count
 
reg [1:0] ad;
reg [WID/2-1:0] r0;
reg [WID-1:0] q0;
reg [WID-1:0] aa;
reg [WID/2-1:0] bb;
reg [WID-1:0] q;
reg [WID/2-1:0] r;
 
wire [WID/2:0] dif = r0 - bb;
reg [2:0] state;
reg divByZero;
 
always @(posedge clk)
if (rst) begin
cnt <= 8'd0;
state <= IDLE;
divByZero <= 1'b0;
q <= {WID{1'b0}};
r <= {WID/2{1'b0}};
r0 <= {WID/2{1'b0}};
q0 <= {WID{1'b0}};
end
else if (ce) begin
case(state)
IDLE:
if (ld) begin
state <= DIV;
cnt <= 8'd0;
r0 <= {WID/2{1'b0}};
if (su) begin
q0 <= a[WID-1] ? -a : a;
bb <= ri ? (b[WID/2-1] ? -b : b) : (i[WID/2-1] ? -i : i);
end
else begin
q0 <= a;
bb <= ri ? b : i;
end
divByZero <= b=={WID/2{1'b0}};
if (b=={WID/2{1'b0}}) begin
q <= {WID-1{1'b1}};
state <= IDLE;
end
end
DIV:
if (cnt <= WID) begin
cnt <= cnt + 8'd1;
q0[0] <= ~dif[WID/2-1];
q0[WID-1:1] <= q0[WID-2:0];
r0[0] <= q0[WID-1];
if (~dif[WID/2-1])
r0[WID/2-1:1] <= dif[WID/2-1:0];
else
r0[WID/2-1:1] <= r0 [WID/2-2:0];
end
else
state <= SGN;
SGN:
begin
if (a[WID-1]^b[WID/2-1] && su)
q <= -q0;
else
q <= q0;
if (a[WID-1] & su)
r <= -r0[WID/2-1:1];
else
r <= r0[WID/2-1:1];
state <= IDLE;
end
default:
state <= IDLE;
endcase
end
 
assign done = state==IDLE;
 
endmodule
 
 
module divr2_tb();
 
reg rst;
reg clk;
reg ld;
reg [6:0] cnt;
 
wire ce = 1'b1;
wire [31:0] a = -32'd1283;
wire [31:0] b = -32'd14;
wire [31:0] q;
wire [31:0] r;
wire done;
 
initial begin
clk = 1;
rst = 0;
#100 rst = 1;
#100 rst = 0;
end
 
always #10 clk = ~clk; // 50 MHz
 
always @(posedge clk)
if (rst)
cnt <= 0;
else begin
ld <= 0;
cnt <= cnt + 1;
if (cnt == 3)
ld <= 1;
$display("ld=%b q=%h r=%h done=%b", ld, q, r, done);
end
 
 
divr2 divu0(.rst(rst), .clk(clk), .ce(ce), .ld(ld), .su(1'b1), .ri(1'b0), .a(a), .b(b), .i(b), .q(q), .r(r), .divByZero(), .done(done) );
 
endmodule
 
 
 
/trunk/rtl/verilog/wb_task.v
0,0 → 1,147
 
task code_read;
begin
cyc_type <= `CT_CODE;
cyc_o <= 1'b1;
stb_o <= 1'b1;
we_o <= 1'b0;
adr_o <= csip;
end
endtask
 
task read;
input [2:0] ct;
input [19:0] ad;
begin
cyc_type <= ct;
cyc_o <= 1'b1;
stb_o <= 1'b1;
we_o <= 1'b0;
adr_o <= ad;
end
endtask
 
task pause_read;
begin
cyc_type <= `CT_PASSIVE;
stb_o <= 1'b0;
end
endtask
 
task write;
input [2:0] ct;
input [19:0] ad;
input [7:0] dat;
begin
cyc_type <= ct;
cyc_o <= 1'b1;
stb_o <= 1'b1;
we_o <= 1'b1;
adr_o <= ad;
dat_o <= dat;
end
endtask
 
task nack;
begin
cyc_type <= `CT_PASSIVE;
cyc_o <= 1'b0;
stb_o <= 1'b0;
we_o <= 1'b0;
adr_o <= 20'd0;
dat_o <= 8'd0;
end
endtask
 
task nack_ir;
begin
nack();
ir <= dat_i;
ip <= ip_inc;
end
endtask
 
task nack_ir2;
begin
nack();
ir2 <= dat_i;
ip <= ip_inc;
end
endtask
 
task pause_code_read;
begin
cyc_type <= `CT_PASSIVE;
stb_o <= 1'b0;
ip <= ip_inc;
end
endtask
 
task continue_code_read;
begin
cyc_type <= `CT_CODE;
stb_o <= 1'b1;
adr_o <= csip;
end
endtask
 
task term_code_read;
begin
nack();
ip <= ip_inc;
end
endtask
 
task stack_push;
begin
cyc_type <= `CT_WRMEM;
cyc_o <= 1'b1;
stb_o <= 1'b1;
we_o <= 1'b1;
adr_o <= sssp;
end
endtask
 
task pause_stack_push;
begin
cyc_type <= `CT_PASSIVE;
sp <= sp_dec;
stb_o <= 1'b0;
we_o <= 1'b0;
end
endtask
 
task stack_pop;
begin
cyc_type <= `CT_RDMEM;
lock_o <= 1'b1;
cyc_o <= 1'b1;
stb_o <= 1'b1;
adr_o <= sssp;
end
endtask
 
task pause_stack_pop;
begin
cyc_type <= `CT_PASSIVE;
stb_o <= 1'b0;
sp <= sp_inc;
end
endtask
 
task continue_stack_pop;
begin
cyc_type <= `CT_RDMEM;
stb_o <= 1'b1;
adr_o <= sssp;
end
endtask
 
task stack_pop_nack;
begin
lock_o <= bus_locked;
sp <= sp_inc;
nack();
end
endtask
 
/trunk/rtl/verilog/CALL_IN.v
2,7 → 2,7
// CALL NEAR Indirect
//
// 2009-2012 Robert Finch
// robfinch<remove>@opencores.org
// robfinch<remove>@finitron.ca
//
// 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
20,32 → 20,17
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//
CALL_IN:
if (!cyc_o) begin
cyc_type <= `CT_WRMEM;
cyc_o <= 1'b1;
stb_o <= 1'b1;
we_o <= 1'b1;
adr_o <= sssp;
dat_o <= ip[15:8];
end
if (!cyc_o)
write(`CT_WRMEM,sssp,ip[15:8]);
else if (ack_i) begin
cyc_type <= `CT_PASSIVE;
pause_stack_push();
state <= CALL_IN1;
sp <= sp_dec;
stb_o <= 1'b0;
we_o <= 1'b0;
end
CALL_IN1:
if (!stb_o) begin
cyc_type <= `CT_WRMEM;
cyc_o <= 1'b1;
stb_o <= 1'b1;
we_o <= 1'b1;
adr_o <= sssp;
dat_o <= ip[7:0];
end
if (!stb_o)
write(`CT_WRMEM,sssp,ip[7:0]);
else if (ack_i) begin
cyc_type <= `CT_PASSIVE;
nack();
ea <= {cs,`SEG_SHIFT}+b;
if (mod==2'b11) begin
ip <= b;
53,35 → 38,21
end
else
state <= CALL_IN2;
cyc_o <= 1'b0;
stb_o <= 1'b0;
we_o <= 1'b0;
end
CALL_IN2:
if (!cyc_o) begin
cyc_type <= `CT_RDMEM;
cyc_o <= 1'b1;
stb_o <= 1'b1;
we_o <= 1'b0;
adr_o <= ea;
end
if (!cyc_o)
read(`CT_RDMEM,ea);
else if (ack_i) begin
cyc_type <= `CT_PASSIVE;
stb_o <= 1'b0;
pause_read();
state <= CALL_IN3;
b[7:0] <= dat_i;
end
CALL_IN3:
if (!stb_o) begin
cyc_type <= `CT_RDMEM;
stb_o <= 1'b1;
adr_o <= ea_inc;
end
if (!stb_o)
read(`CT_RDMEM,ea_inc);
else if (ack_i) begin
cyc_type <= `CT_PASSIVE;
nack();
state <= CALL_IN4;
cyc_o <= 1'b0;
stb_o <= 1'b0;
b[15:8] <= dat_i;
end
CALL_IN4:
/trunk/rtl/verilog/IFETCH.v
36,6 → 36,7
//
IFETCH:
begin
$display("CSIP: %h", csip);
// Reset all instruction processing flags at instruction fetch
cyc_type <= `CT_PASSIVE;
mod <= 2'd0;
77,7 → 78,7
end
else begin
state <= IFETCH_ACK;
`INITIATE_CODE_READ
read(`CT_CODE,csip);
inta_o <= 1'b0;
mio_o <= 1'b1;
lock_o <= bus_locked;
86,8 → 87,7
 
IFETCH_ACK:
if (ack_i) begin
`TERMINATE_CODE_READ
ir <= dat_i;
nack_ir();
$display("IR: %h",dat_i);
if (!hasPrefix)
ir_ip <= ip;
106,13 → 106,12
//
XI_FETCH:
begin
`INITIATE_CODE_READ
read(`CT_CODE,csip);
state <= XI_FETCH_ACK;
end
 
XI_FETCH_ACK:
if (ack_i) begin
`TERMINATE_CODE_READ
ir2 <= dat_i;
nack_ir2();
state <= DECODER2;
end
/trunk/rtl/verilog/EACALC.v
3,8 → 3,8
// - calculation of effective address
//
//
// (C) 2009-2012 Robert Finch, Stratford
// robfinch[remove]@opencores.org
// (C) 2009-2013 Robert Finch, Stratford
// robfinch[remove]@finitron.ca
//
//
// This source file is free software: you can redistribute it and/or modify
269,8 → 269,21
// bus_locked <= 1'b1;
state <= FETCH_DATA;
end
8'b1000100x: // Move to memory
begin
$display("EACALC1: state <= STORE_DATA");
if (w && (offsdisp==16'hFFFF)) begin
int_num <= 8'h0d;
state <= INT;
end
else begin
res <= rrro;
state <= STORE_DATA;
end
end
default:
begin
$display("EACALC1: state <= FETCH_DATA");
if (w && (offsdisp==16'hFFFF)) begin
int_num <= 8'h0d;
state <= INT;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.