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 |