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; |