OpenCores
URL https://opencores.org/ocsvn/zet86/zet86/trunk

Subversion Repositories zet86

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 29 to Rev 30
    Reverse comparison

Rev 29 → Rev 30

/trunk/rtl-model/regfile.v
18,31 → 18,45
 
`timescale 1ns/10ps
 
module regfile(a, b, c, cs, ip, d, s, flags, wr, wrfl, wrhi, clk, rst,
addr_a, addr_b, addr_c, addr_d, addr_s, iflags, word_op,
o_byte, c_byte, cx_zero);
// IO Ports
output [15:0] a, b, c, s;
output [15:0] cs;
input [3:0] addr_a, addr_b, addr_c, addr_d;
input [1:0] addr_s;
input [8:0] iflags;
input [31:0] d;
input wrfl, wrhi, word_op, clk, rst, o_byte, c_byte;
input wr;
output cx_zero;
output [15:0] ip;
output reg [8:0] flags;
module regfile (
output [15:0] a,
output [15:0] b,
output [15:0] c,
output [15:0] cs,
output [15:0] ip,
input [31:0] d,
output [15:0] s,
 
output reg [8:0] flags,
 
input wr,
input wrfl,
input wrhi,
input clk,
input rst,
input [ 3:0] addr_a,
input [ 3:0] addr_b,
input [ 3:0] addr_c,
input [ 3:0] addr_d,
input [ 1:0] addr_s,
input [ 8:0] iflags,
input word_op,
input a_byte,
input b_byte,
input c_byte,
output cx_zero,
input wr_ip0
);
 
// Net declarations
reg [15:0] r[15:0];
wire [7:0] a8, b8, c8;
 
// Assignments
assign a = (o_byte & ~addr_a[3]) ? { {8{a8[7]}}, a8} : r[addr_a];
assign a = (a_byte & ~addr_a[3]) ? { {8{a8[7]}}, a8} : r[addr_a];
assign a8 = addr_a[2] ? r[addr_a[1:0]][15:8] : r[addr_a][7:0];
 
assign b = (o_byte & ~addr_b[3]) ? { {8{b8[7]}}, b8} : r[addr_b];
assign b = (b_byte & ~addr_b[3]) ? { {8{b8[7]}}, b8} : r[addr_b];
assign b8 = addr_b[2] ? r[addr_b[1:0]][15:8] : r[addr_b][7:0];
 
assign c = (c_byte & ~addr_c[3]) ? { {8{c8[7]}}, c8} : r[addr_c];
77,5 → 91,6
end
if (wrfl) flags <= iflags;
if (wrhi) r[4'd2] <= d[31:16];
r[14] <= wr_ip0 ? ip : r[14];
end
endmodule
/trunk/rtl-model/alu.v
18,17 → 18,20
 
`timescale 1ns/10ps
 
module alu(x, y, out, t, func, iflags, oflags, word_op, seg, off, clk);
// IO ports
input [31:0] x;
input [15:0] y;
input [2:0] t, func;
input [15:0] iflags;
input word_op;
input [15:0] seg, off;
output [31:0] out;
output [8:0] oflags;
input clk;
module alu (
input [31:0] x,
input [15:0] y,
output [31:0] out,
input [ 2:0] t,
input [ 2:0] func,
input [15:0] iflags,
output [ 8:0] oflags,
input word_op,
input [15:0] seg,
input [15:0] off,
input clk,
output div_exc
);
 
// Net declarations
wire [15:0] add, log, shi, rot;
41,6 → 44,7
wire ofi, sfi, zfi, afi, pfi, cfi;
wire ofo, sfo, zfo, afo, pfo, cfo;
wire flags_unchanged;
wire dexc;
 
// Module instances
addsub add1 (x[15:0], y, add, func, word_op, cfi, cf_add, af_add, of_add);
61,7 → 65,8
.word_op (word_op),
.cfo (cf_mul),
.ofo (of_mul),
.clk (clk)
.clk (clk),
.exc (dexc)
);
 
bitlog log4 (x[15:0], y, log, func, cf_log, of_log);
98,6 → 103,9
|| t == 3'd4 && func == 3'd2
|| t == 3'd5 && y[4:0] == 5'h0
|| t == 3'd6 && y[4:0] == 5'h0);
 
assign div_exc = func[1] && (t==3'd3) && dexc;
 
endmodule
 
module addsub (
204,7 → 212,8
input word_op,
output cfo,
output ofo,
input clk
input clk,
output exc
);
 
// Net declarations
211,7 → 220,13
wire as, bs, cfs, cfu;
wire [16:0] a, b;
wire [33:0] p;
wire div0, over, ovf, mint;
 
wire [33:0] zi;
wire [16:0] di;
wire [17:0] q;
wire [17:0] s;
 
// Module instantiations
mult signmul17 (
.clk (clk),
220,6 → 235,17
.p (p)
);
 
div_su #(34) dut (
.clk (clk),
.ena (1'b1),
.z (zi),
.d (di),
.q (q),
.s (s),
.ovf (ovf),
.div0 (div0)
);
 
// Sign ext. for imul
assign as = f[0] & (word_op ? x[15] : x[7]);
assign bs = f[0] & (word_op ? y[15] : y[7]);
226,8 → 252,20
assign a = word_op ? { as, x[15:0] }
: { {9{as}}, x[7:0] };
assign b = word_op ? { bs, y } : { {9{bs}}, y[7:0] };
assign o = p[31:0];
 
assign zi = word_op ? (f[0] ? { {2{x[31]}}, x }
: { 2'b0, x })
: (f[0] ? { {18{x[15]}}, x[15:0] }
: { 18'b0, x[15:0] });
 
assign di = word_op ? (f[0] ? { y[15], y } : { 1'b0, y })
: (f[0] ? { {9{y[7]}}, y[7:0] }
: { 9'h000, y[7:0] });
 
assign o = f[1] ? ( word_op ? {s[15:0], q[15:0]}
: {16'h0, s[7:0], q[7:0]})
: p[31:0];
 
assign ofo = cfo;
assign cfo = !(f[0] ? cfs : cfu);
assign cfu = word_op ? (o[31:16] == 16'h0)
234,6 → 272,15
: (o[15:8] == 8'h0);
assign cfs = word_op ? (o[31:16] == {16{o[15]}})
: (o[15:8] == {8{o[7]}});
 
// Exceptions
assign over = word_op ? (f[0] ? (q[17:16]!={2{q[15]}})
: (q[17:16]!=2'b0) )
: (f[0] ? (q[17:8]!={10{q[7]}})
: (q[17:8]!=10'h000) );
assign mint = f[0] & (word_op ? (x==32'h80000000)
: (x==16'h8000));
assign exc = div0 | ovf | over | mint;
endmodule
 
module bitlog(x, y, out, func, cfo, ofo);
/trunk/rtl-model/exec.v
44,7 → 44,9
output we,
output m_io,
output byteop,
input mem_rdy
input mem_rdy,
output div_exc,
input wrip0
);
 
// Net declarations
53,7 → 55,7
wire [3:0] addr_a, addr_b, addr_c, addr_d;
wire [2:0] t, func;
wire [1:0] addr_s;
wire wrfl, high, memalu, a_byte, c_byte;
wire wrfl, high, memalu, r_byte, c_byte;
wire wr, wr_reg, block;
wire wr_cnd;
wire jmp;
60,14 → 62,18
wire mem_op, b_imm;
wire [8:0] flags, iflags, oflags;
wire [4:0] logic_flags;
wire wordop;
wire alu_word;
wire a_byte;
wire b_byte;
wire wr_high;
wire dive;
 
// Module instances
alu alu0( {c, a }, bus_b, aluout, t, func, alu_iflags, oflags,
wordop, s, off, clk);
alu_word, s, off, clk, dive);
regfile reg0( a, b, c, cs, ip, {aluout[31:16], omemalu}, s, flags, wr_reg, wrfl,
high, clk, rst, addr_a, addr_b, addr_c, addr_d, addr_s, iflags,
~byteop, a_byte, c_byte, cx_zero);
wr_high, clk, rst, addr_a, addr_b, addr_c, addr_d, addr_s, iflags,
~byteop, a_byte, b_byte, c_byte, cx_zero, wrip0);
jmp_cond jc0( logic_flags, addr_b, addr_c[0], c, jmp);
 
// Assignments
88,7 → 94,7
assign mem_op = ir[31];
assign m_io = ir[32];
assign b_imm = ir[33];
assign a_byte = ir[34];
assign r_byte = ir[34];
assign c_byte = ir[35];
 
assign omemalu = memalu ? aluout[15:0] : memout;
96,7 → 102,8
 
assign addr = aluout[19:0];
assign wr_data = c;
assign wr_reg = (wr | (jmp & wr_cnd)) && !block;
assign wr_reg = (wr | (jmp & wr_cnd)) && !block && !div_exc;
assign wr_high = high && !block && !div_exc;
assign of = flags[8];
assign zf = flags[3];
assign block = mem_op && !mem_rdy;
106,7 → 113,10
1'b1, flags[0] };
assign logic_flags = { flags[8], flags[4], flags[3], flags[1], flags[0] };
 
assign wordop = (t==3'b011) ? ~a_byte : ~byteop;
assign alu_word = (t==3'b011) ? ~r_byte : ~byteop;
assign a_byte = (t==3'b011 && func[1]) ? 1'b0 : r_byte;
assign b_byte = r_byte;
assign div_exc = dive && wr;
 
`ifdef DEBUG
assign x = a;
/trunk/rtl-model/cpu.v
57,6 → 57,8
wire [19:0] addr_exec, addr_fetch;
wire byte_fetch, byte_exec, fetch_or_exec;
wire of, zf, cx_zero;
wire div_exc;
wire inopco_st;
 
// Module instantiations
fetch fetch0 (
79,7 → 81,9
.cx_zero (cx_zero),
.bytefetch (byte_fetch),
.fetch_or_exec (fetch_or_exec),
.mem_rdy (ack_i)
.mem_rdy (ack_i),
.div_exc (div_exc),
.inopco_st (inopco_st)
);
 
exec exec0 (
104,7 → 108,9
.we (we_o),
.m_io (mio_o),
.byteop (byte_exec),
.mem_rdy (ack_i)
.mem_rdy (ack_i),
.div_exc (div_exc),
.wrip0 (inopco_st)
);
 
// Assignments
/trunk/rtl-model/fetch.v
39,7 → 39,9
output [19:0] pc,
output bytefetch,
output fetch_or_exec,
input mem_rdy
input mem_rdy,
input div_exc,
output inopco_st
);
 
// Registers, nets and parameters
62,6 → 64,7
wire next_in_opco, next_in_exec;
wire block;
wire need_modrm, need_off, need_imm, off_size, imm_size;
wire dive;
 
reg [7:0] opcode_l, modrm_l;
reg [15:0] off_l, imm_l;
68,13 → 71,13
reg [1:0] pref_l;
 
// Module instantiation
decode decode0(opcode, modrm, off_l, imm_l, pref_l[1], clk, rst, block,
exec_st, need_modrm, need_off, need_imm, off_size, imm_size,
rom_ir, off, imm_d, end_seq);
decode decode0(opcode, modrm, off_l, imm_l, pref_l[1], clk, rst, block,
exec_st, div_exc, need_modrm, need_off, need_imm, off_size,
imm_size, rom_ir, off, imm_d, end_seq, dive);
next_or_not nn0(pref_l, opcode[7:1], cx_zero, zf, next_in_opco,
next_in_exec);
nstate ns0(state, prefix, need_modrm, need_off, need_imm, end_seq,
rom_ir[28:23], of, next_in_opco, next_in_exec, block,
rom_ir[28:23], of, next_in_opco, next_in_exec, block, div_exc,
next_state);
 
// Assignments
87,13 → 90,15
assign bytefetch = (state == offse_st) ? ~off_size
: ((state == immed_st) ? ~imm_size : 1'b1);
assign exec_st = (state == execu_st);
assign imm = (state == execu_st) ? imm_d
: ((state == offse_st) & off_size
assign imm = (state == execu_st) ? imm_d
: (((state == offse_st) & off_size
| (state == immed_st) & imm_size) ? 16'd2
: 16'd1;
: 16'd1);
assign prefix = (opcode[7:1]==7'b1111_001);
assign block = ir[`MEM_OP] && !mem_rdy;
 
assign inopco_st = (state == opcod_st);
 
// Behaviour
always @(posedge clk)
if (rst)
163,6 → 168,7
input next_in_opco,
input next_in_exec,
input block,
input div_exc,
output [2:0] next_state
);
 
178,7 → 184,7
// Assignments
assign into = (ftype==6'b111_010);
assign end_into = into ? ~of : end_seq;
assign end_instr = end_into && !next_in_exec;
assign end_instr = !div_exc && end_into && !next_in_exec;
 
assign n_state = (state == opcod_st) ? (prefix ? opcod_st
: (next_in_opco ? opcod_st
230,6 → 236,7
input rst,
input block,
input exec_st,
input div_exc,
 
output need_modrm,
output need_off,
240,7 → 247,8
output [`IR_SIZE-1:0] ir,
output [15:0] off_o,
output [15:0] imm_o,
output end_seq
output end_seq,
output reg dive
);
 
// Net declarations
259,15 → 267,19
ir, off_o, imm_o);
 
// Assignments
assign seq_addr = base_addr + seq;
assign seq_addr = (dive ? `INTD : base_addr) + seq;
 
// Behaviour
// seq
always @(posedge clk)
if (rst) seq <= `SEQ_ADDR_WIDTH'd0;
else if (!block)
seq <= (exec_st && !end_seq && !rst) ? (seq + `SEQ_ADDR_WIDTH'd1)
: `SEQ_ADDR_WIDTH'd0;
 
// dive
always @(posedge clk)
if (rst) dive <= 1'b0;
else dive <= block ? dive : (div_exc ? 1'b1 : (dive ? !end_seq : 1'b0));
endmodule
 
module opcode_deco (
1306,7 → 1318,19
src <= rm;
dst <= rm;
end
 
/*
8'b1101_0100: // aam
begin
seq_addr <= `AAM;
need_modrm <= 1'b0;
need_off <= 1'b0;
need_imm <= 1'b1;
off_size <= 1'b0;
imm_size <= 1'b0;
src <= 4'b0;
dst <= 4'b0;
end
*/
8'b1101_0101: // aad
begin
seq_addr <= `AAD;
1503,6 → 1527,10
(b ? `MULRB : `MULRW) : (b ? `MULMB : `MULMW);
3'b101: seq_addr <= (mod==2'b11) ?
(b ? `IMULRB : `IMULRW) : (b ? `IMULMB : `IMULMW);
3'b110: seq_addr <= (mod==2'b11) ?
(b ? `DIVRB : `DIVRW) : (b ? `DIVMB : `DIVMW);
3'b111: seq_addr <= (mod==2'b11) ?
(b ? `IDIVRB : `IDIVRW) : (b ? `IDIVMB : `IDIVMW);
default: seq_addr <= `NOP;
endcase
 
/trunk/rtl-model/util/div_uu.v
0,0 → 1,207
/////////////////////////////////////////////////////////////////////
//// ////
//// Non-restoring unsigned divider ////
//// ////
//// Author: Richard Herveille ////
//// richard@asics.ws ////
//// www.asics.ws ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2002 Richard Herveille ////
//// richard@asics.ws ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
//// POSSIBILITY OF SUCH DAMAGE. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
// CVS Log
//
// $Id: div_uu.v,v 1.1 2008-10-10 04:04:11 zeus Exp $
//
// $Date: 2008-10-10 04:04:11 $
// $Revision: 1.1 $
// $Author: zeus $
// $Locker: $
// $State: Exp $
//
// Change History:
// $Log: not supported by cvs2svn $
// Revision 1.3 2003/09/17 13:08:53 rherveille
// Fixed a bug in the remainder output. Changed a hard value into the required parameter.
// Fixed a bug in the testbench.
//
// Revision 1.2 2002/10/31 13:54:58 rherveille
// Fixed a bug in the remainder output of div_su.v
//
// Revision 1.1.1.1 2002/10/29 20:29:10 rherveille
//
//
//
 
//synopsys translate_off
`include "timescale.v"
//synopsys translate_on
 
module div_uu(clk, ena, z, d, q, s, div0, ovf);
 
//
// parameters
//
parameter z_width = 16;
parameter d_width = z_width /2;
//
// inputs & outputs
//
input clk; // system clock
input ena; // clock enable
 
input [z_width -1:0] z; // divident
input [d_width -1:0] d; // divisor
output [d_width -1:0] q; // quotient
output [d_width -1:0] s; // remainder
output div0;
output ovf;
reg [d_width-1:0] q;
reg [d_width-1:0] s;
reg div0;
reg ovf;
 
//
// functions
//
function [z_width:0] gen_s;
input [z_width:0] si;
input [z_width:0] di;
begin
if(si[z_width])
gen_s = {si[z_width-1:0], 1'b0} + di;
else
gen_s = {si[z_width-1:0], 1'b0} - di;
end
endfunction
 
function [d_width-1:0] gen_q;
input [d_width-1:0] qi;
input [z_width:0] si;
begin
gen_q = {qi[d_width-2:0], ~si[z_width]};
end
endfunction
 
function [d_width-1:0] assign_s;
input [z_width:0] si;
input [z_width:0] di;
reg [z_width:0] tmp;
begin
if(si[z_width])
tmp = si + di;
else
tmp = si;
 
assign_s = tmp[z_width-1:z_width-d_width];
end
endfunction
 
//
// variables
//
reg [d_width-1:0] q_pipe [d_width-1:0];
reg [z_width:0] s_pipe [d_width:0];
reg [z_width:0] d_pipe [d_width:0];
 
reg [d_width:0] div0_pipe, ovf_pipe;
//
// perform parameter checks
//
// synopsys translate_off
initial
begin
if(d_width !== z_width / 2)
$display("div.v parameter error (d_width != z_width/2).");
end
// synopsys translate_on
 
integer n0, n1, n2, n3;
 
// generate divisor (d) pipe
always @(d)
d_pipe[0] <= {1'b0, d, {(z_width-d_width){1'b0}} };
 
always @(posedge clk)
if(ena)
for(n0=1; n0 <= d_width; n0=n0+1)
d_pipe[n0] <= #1 d_pipe[n0-1];
 
// generate internal remainder pipe
always @(z)
s_pipe[0] <= z;
 
always @(posedge clk)
if(ena)
for(n1=1; n1 <= d_width; n1=n1+1)
s_pipe[n1] <= #1 gen_s(s_pipe[n1-1], d_pipe[n1-1]);
 
// generate quotient pipe
always @(posedge clk)
q_pipe[0] <= #1 0;
 
always @(posedge clk)
if(ena)
for(n2=1; n2 < d_width; n2=n2+1)
q_pipe[n2] <= #1 gen_q(q_pipe[n2-1], s_pipe[n2]);
 
 
// flags (divide_by_zero, overflow)
always @(z or d)
begin
ovf_pipe[0] <= !(z[z_width-1:d_width] < d);
div0_pipe[0] <= ~|d;
end
 
always @(posedge clk)
if(ena)
for(n3=1; n3 <= d_width; n3=n3+1)
begin
ovf_pipe[n3] <= #1 ovf_pipe[n3-1];
div0_pipe[n3] <= #1 div0_pipe[n3-1];
end
 
// assign outputs
always @(posedge clk)
if(ena)
ovf <= #1 ovf_pipe[d_width];
 
always @(posedge clk)
if(ena)
div0 <= #1 div0_pipe[d_width];
 
always @(posedge clk)
if(ena)
q <= #1 gen_q(q_pipe[d_width-1], s_pipe[d_width]);
 
always @(posedge clk)
if(ena)
s <= #1 assign_s(s_pipe[d_width], d_pipe[d_width]);
endmodule
 
 
 
/trunk/rtl-model/util/div_su.v
0,0 → 1,167
/////////////////////////////////////////////////////////////////////
//// ////
//// Non-restoring signed by unsigned divider ////
//// Uses the non-restoring unsigned by unsigned divider ////
//// ////
//// Author: Richard Herveille ////
//// richard@asics.ws ////
//// www.asics.ws ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2002 Richard Herveille ////
//// richard@asics.ws ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
//// POSSIBILITY OF SUCH DAMAGE. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
// CVS Log
//
// $Id: div_su.v,v 1.1 2008-10-10 04:04:11 zeus Exp $
//
// $Date: 2008-10-10 04:04:11 $
// $Revision: 1.1 $
// $Author: zeus $
// $Locker: $
// $State: Exp $
//
// Change History:
// $Log: not supported by cvs2svn $
// Revision 1.2 2002/10/31 13:54:58 rherveille
// Fixed a bug in the remainder output of div_su.v
//
// Revision 1.1.1.1 2002/10/29 20:29:09 rherveille
//
//
//
 
//synopsys translate_off
`include "timescale.v"
//synopsys translate_on
 
module div_su(clk, ena, z, d, q, s, div0, ovf);
 
//
// parameters
//
parameter z_width = 16;
parameter d_width = z_width /2;
//
// inputs & outputs
//
input clk; // system clock
input ena; // clock enable
 
input [z_width-1:0] z; // divident
input [d_width-1:0] d; // divisor
output [d_width :0] q; // quotient
output [d_width :0] s; // remainder
output div0;
output ovf;
 
reg [d_width:0] q, s;
reg div0;
reg ovf;
 
//
// variables
//
reg [z_width -1:0] iz;
reg [d_width -1:0] id;
reg [d_width +1:0] szpipe, sdpipe;
 
wire [d_width -1:0] iq, is;
wire idiv0, iovf;
 
//
// module body
//
 
// check d, take abs value
always @(posedge clk)
if (ena)
if (d[d_width-1])
id <= #1 ~d +1'h1;
else
id <= #1 d;
 
// check z, take abs value
always @(posedge clk)
if (ena)
if (z[z_width-1])
iz <= #1 ~z +1'h1;
else
iz <= #1 z;
 
// generate szpipe (z sign bit pipe)
integer n;
always @(posedge clk)
if(ena)
begin
szpipe[0] <= #1 z[z_width-1];
 
for(n=1; n <= d_width+1; n=n+1)
szpipe[n] <= #1 szpipe[n-1];
end
 
// generate sdpipe (d sign bit pipe)
integer m;
always @(posedge clk)
if(ena)
begin
sdpipe[0] <= #1 d[d_width-1];
 
for(m=1; m <= d_width+1; m=m+1)
sdpipe[m] <= #1 sdpipe[m-1];
end
 
// hookup non-restoring divider
div_uu #(z_width, d_width)
divider (
.clk(clk),
.ena(ena),
.z(iz),
.d(id),
.q(iq),
.s(is),
.div0(idiv0),
.ovf(iovf)
);
 
// correct divider results if 'd' was negative
always @(posedge clk)
if(ena)
begin
q <= #1 (szpipe[d_width+1]^sdpipe[d_width+1]) ?
((~iq) + 1'h1) : ({1'b0, iq});
s <= #1 (szpipe[d_width+1]) ?
((~is) + 1'h1) : ({1'b0, is});
end
 
// delay flags same as results
always @(posedge clk)
if(ena)
begin
div0 <= #1 idiv0;
ovf <= #1 iovf;
end
endmodule
/trunk/tests/i86/18_div.s
0,0 → 1,340
.code16
start:
movw $256, %sp
 
# Exception 0 handler
movw $0x1000, (0)
movw $0xf000, (2)
 
movw $256, %bp
 
# div word tests
# easy test
movw $0x0, %dx
movw $0x14, %ax
movw $0x5, %bx
 
movw $0x2, (%bp)
divw %bx
addw $0x2, %bp
 
movw %ax, (128)
movw %bx, (130)
movw %dx, (4)
pushf
 
 
movw $0xa320, %dx
movw $0xc3da, %ax
movw $0xffff, (6)
 
movw $0x4, (%bp)
divw (6)
addw $0x2, %bp
 
movw %ax, (8)
movw %dx, (10)
pushf
 
 
movw $0xffff, %dx
movw $0xffff, %ax
movw $0x1, %cx
 
movw $0x2, (%bp)
divw %cx
addw $0x2, %bp
 
movw %ax, (12)
movw %cx, (14)
movw %dx, (16)
pushf
 
 
movw $0xffff, %dx
movw $0xffff, %ax
movw $0xffff, (18)
 
movw $0x4, (%bp)
divw (18)
addw $0x2, %bp
 
movw %ax, (20)
movw %dx, (22)
pushf
 
 
movw $0xfbb4, %dx
movw $0xc3da, %ax
movw $0xae8e, %cx
 
movw $0x2, (%bp)
divw %cx
addw $0x2, %bp
 
movw %ax, (24)
movw %cx, (26)
movw %dx, (28)
pushf
 
 
movw $0x25c9, %dx
movw $0xf110, %ax
 
movw $0x2, (%bp)
divw %ax
addw $0x2, %bp
 
movw %ax, (30)
movw %dx, (32)
pushf
 
 
# div byte tests
# easy test
movw $0x14, %ax
movw $0x5, %bx
 
movw $0x2, (%bp)
divb %bl
addw $0x2, %bp
 
movw %ax, (34)
movw %bx, (36)
movw %dx, (38)
pushf
 
movw $0xa320, %dx
movw $0xc3da, %ax
movw $0xff, (40)
 
movw $0x4, (%bp)
divb (40)
addw $0x2, %bp
 
movw %ax, (42)
movw %dx, (44)
pushf
 
movw $0xffff, %ax
movb $0x1, %dh
 
movw $0x2, (%bp)
divb %dh
addw $0x2, %bp
 
movw %ax, (46)
movw %dx, (48)
pushf
 
movw $0xffff, %ax
movw $0xffff, (50)
 
movw $0x4, (%bp)
divb (51)
addw $0x2, %bp
 
movw %ax, (52)
movw %dx, (54)
pushf
 
movw $0x008a, %ax
movw $0xae8e, %cx
 
movw $0x2, (%bp)
divb %cl
addw $0x2, %bp
 
movw %ax, (56)
movw %cx, (58)
pushf
 
movw $0x0669, %dx
movw $0x89f3, %ax
 
movw $0x2, (%bp)
divb %al
addw $0x2, %bp
 
movw %ax, (60)
movw %dx, (62)
pushf
 
# idiv word tests
# easy test
movw $0x0, %dx
movw $0x14, %ax
movw $0xfa, %bx
 
movw $0x2, (%bp)
idivw %bx
addw $0x2, %bp
 
movw %ax, (64)
movw %bx, (66)
movw %dx, (68)
pushf
 
 
movw $0xa320, %dx
movw $0xc3da, %ax
movw $0xffff, (70)
 
movw $0x4, (%bp)
idivw (70)
addw $0x2, %bp
 
movw %ax, (72)
movw %dx, (74)
pushf
 
 
movw $0xffff, %dx
movw $0xffff, %ax
movw $0x1, %cx
 
movw $0x2, (%bp)
idivw %cx
addw $0x2, %bp
 
movw %ax, (76)
movw %cx, (78)
movw %dx, (80)
pushf
 
 
movw $0xffff, %dx
movw $0xffff, %ax
movw $0xffff, (82)
 
movw $0x4, (%bp)
idivw (82)
addw $0x2, %bp
 
movw %ax, (84)
movw %dx, (86)
pushf
 
 
movw $0xfbb4, %dx
movw $0xc3da, %ax
movw $0xae8e, %cx
 
movw $0x2, (%bp)
idivw %cx
addw $0x2, %bp
 
movw %ax, (88)
movw %cx, (90)
movw %dx, (92)
pushf
 
 
movw $0x25c9, %dx
movw $0xf110, %ax
 
movw $0x2, (%bp)
idivw %ax
addw $0x2, %bp
 
movw %ax, (94)
movw %dx, (96)
pushf
 
# idiv byte tests
# easy test
movw $0x14, %ax
movw $0x5, %bx
 
movw $0x2, (%bp)
idivb %bl
addw $0x2, %bp
 
movw %ax, (98)
movw %bx, (100)
movw %dx, (102)
pushf
 
 
movw $0xa320, %dx
movw $0xc3da, %ax
movw $0xff, (104)
 
movw $0x4, (%bp)
idivb (104)
addw $0x2, %bp
 
movw %ax, (106)
movw %dx, (108)
pushf
 
 
movw $0xffff, %ax
movb $0x1, %dh
 
movw $0x2, (%bp)
idivb %dh
addw $0x2, %bp
 
movw %ax, (110)
movw %dx, (112)
pushf
 
 
movw $0xffff, %ax
movw $0xffff, (114)
 
movw $0x4, (%bp)
idivb (115)
addw $0x2, %bp
 
movw %ax, (116)
movw %dx, (118)
pushf
 
 
movw $0x008a, %ax
movw $0xae8e, %cx
 
movw $0x2, (%bp)
idivb %cl
addw $0x2, %bp
 
movw %ax, (120)
movw %cx, (122)
pushf
 
 
movw $0x0669, %dx
movw $0x89f3, %ax
 
movw $0x2, (%bp)
idivb %al
addw $0x2, %bp
 
movw %ax, (124)
movw %dx, (126)
pushf
hlt
 
# Exception handler (int 0)
.org 0x1000
push %ax
push %di
movw (%bp), %ax
movw %sp, %si
addw $4, %si
movw (%si), %si
movw %si, (%bp)
addw %ax, %si
movw %sp, %di
addw $4, %di
movw %si, (%di)
pop %di
pop %ax
iret
 
.org 65520
jmp start
.org 65535
.byte 0xff
/trunk/tests/i86/.bochsrc
1,4 → 1,4
romimage: file=17_mul.out
romimage: file=18_div.out
cpu: count=1, ips=10000000, reset_on_triple_fault=1
megs: 2
vgaromimage: file=$BXSHARE/VGABIOS-lgpl-latest
/trunk/sim/modelsim/tb.do
1,7 → 1,7
vdel -all -lib work
vmap unisims /opt/Xilinx/10.1/modelsim/verilog/unisims
vlib work
vlog -work work -lint +incdir+../../rtl-model ../../rtl-model/regfile.v ../../rtl-model/alu.v ../../rtl-model/cpu.v ../../rtl-model/exec.v ../../rtl-model/fetch.v ../../rtl-model/jmp_cond.v ../../rtl-model/util/primitives.v ../../rtl-model/rotate.v
vlog -work work -lint +incdir+../../rtl-model +incdir+.. ../../rtl-model/regfile.v ../../rtl-model/alu.v ../../rtl-model/cpu.v ../../rtl-model/exec.v ../../rtl-model/fetch.v ../../rtl-model/jmp_cond.v ../../rtl-model/util/primitives.v ../../rtl-model/util/div_su.v ../../rtl-model/util/div_uu.v ../../rtl-model/rotate.v
vlog -work work +incdir+.. ../memory.v ../testbench.v ../mult.v
vlog -work unisims /opt/Xilinx/10.1/ISE/verilog/src/glbl.v
vsim -L /opt/Xilinx/10.1/modelsim/verilog/unisims -novopt -t ns work.testbench work.glbl
37,4 → 37,6
add wave -label we /testbench/we
add wave -label ack_i /testbench/ack_i
add wave -label fetch_or_exec /testbench/cpu0/fetch_or_exec
add wave -divider mul
add wave -radix hexadecimal -r /testbench/cpu0/exec0/alu0/mul3/dut/*
#run 50us

powered by: WebSVN 2.1.0

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