URL
https://opencores.org/ocsvn/zet86/zet86/trunk
Subversion Repositories zet86
Compare Revisions
- This comparison shows the changes necessary to convert path
/zet86
- from Rev 54 to Rev 55
- ↔ Reverse comparison
Rev 54 → Rev 55
/trunk/rtl-model/defines.v
File deleted
/trunk/rtl-model/regfile.v
File deleted
\ No newline at end of file
/trunk/rtl-model/rotate.v
File deleted
/trunk/rtl-model/alu.v
File deleted
/trunk/rtl-model/exec.v
File deleted
/trunk/rtl-model/cpu.v
File deleted
/trunk/rtl-model/jmp_cond.v
File deleted
/trunk/rtl-model/util/div_su.v
File deleted
/trunk/rtl-model/util/div_uu.v
File deleted
/trunk/rtl-model/util/primitives.v
File deleted
/trunk/rtl-model/fetch.v
File deleted
/trunk/cores/zet/rtl/defines.v
0,0 → 1,27
/* |
* Copyright (c) 2008 Zeus Gomez Marmolejo <zeus@opencores.org> |
* |
* This file is part of the Zet processor. This processor is free |
* hardware; you can redistribute it and/or modify it under the terms of |
* the GNU General Public License as published by the Free Software |
* Foundation; either version 3, or (at your option) any later version. |
* |
* Zet is distrubuted 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 Zet; see the file COPYING. If not, see |
* <http://www.gnu.org/licenses/>. |
*/ |
|
`include "rom_def.v" |
|
`define IR_SIZE 36 |
`define MEM_OP 31 |
`define ADD_IP `IR_SIZE'bx__0__1__0__1__10_001_001__0__01__0__0_1111_xxxx_xxxx_1111_xx |
`define OP_NOP 8'h90 |
|
//`define DEBUG 1 |
//`define DEBUG_TRACE 1 |
trunk/cores/zet/rtl/defines.v
Property changes :
Added: svn:mergeinfo
## -0,0 +0,0 ##
Index: trunk/cores/zet/rtl/regfile.v
===================================================================
--- trunk/cores/zet/rtl/regfile.v (nonexistent)
+++ trunk/cores/zet/rtl/regfile.v (revision 55)
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2008 Zeus Gomez Marmolejo
+ *
+ * This file is part of the Zet processor. This processor is free
+ * hardware; you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by the Free Software
+ * Foundation; either version 3, or (at your option) any later version.
+ *
+ * Zet is distrubuted 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 Zet; see the file COPYING. If not, see
+ * .
+ */
+
+`timescale 1ns/10ps
+
+`include "defines.v"
+
+module regfile (
+`ifdef DEBUG
+ output [15:0] ax,
+ output [15:0] dx,
+ output [15:0] bp,
+ output [15:0] si,
+ output [15:0] es,
+`endif
+
+ 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
+`ifdef DEBUG
+ assign ax = r[0];
+ assign dx = r[2];
+ assign bp = r[5];
+ assign si = r[6];
+ assign es = r[8];
+`endif
+ 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 = (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];
+ assign c8 = addr_c[2] ? r[addr_c[1:0]][15:8] : r[addr_c][7:0];
+
+ assign s = r[{2'b10,addr_s}];
+
+ assign cs = r[9];
+ assign cx_zero = (addr_d==4'd1) ? (d==16'd0) : (r[1]==16'd0);
+
+ assign ip = r[15];
+
+ // Behaviour
+ always @(posedge clk)
+ if (rst) begin
+ r[0] <= 16'd0; r[1] <= 16'd0;
+ r[2] <= 16'd0; r[3] <= 16'd0;
+ r[4] <= 16'd0; r[5] <= 16'd0;
+ r[6] <= 16'd0; r[7] <= 16'd0;
+ r[8] <= 16'd0; r[9] <= 16'hf000;
+ r[10] <= 16'd0; r[11] <= 16'd0;
+ r[12] <= 16'd0; r[13] <= 16'd0;
+ r[14] <= 16'd0; r[15] <= 16'hfff0;
+ flags <= 9'd0;
+ end else
+ begin
+ if (wr) begin
+ if (word_op | addr_d[3:2]==2'b10)
+ r[addr_d] <= word_op ? d[15:0] : {{8{d[7]}},d[7:0]};
+ else if (addr_d[3]~^addr_d[2]) r[addr_d][7:0] <= d[7:0];
+ else r[{2'b0,addr_d[1:0]}][15:8] <= d[7:0];
+ end
+ if (wrfl) flags <= iflags;
+ if (wrhi) r[4'd2] <= d[31:16];
+ if (wr_ip0) r[14] <= ip;
+ end
+endmodule
\ No newline at end of file
trunk/cores/zet/rtl/regfile.v
Property changes :
Added: svn:mergeinfo
## -0,0 +0,0 ##
Index: trunk/cores/zet/rtl/rotate.v
===================================================================
--- trunk/cores/zet/rtl/rotate.v (nonexistent)
+++ trunk/cores/zet/rtl/rotate.v (revision 55)
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2008 Zeus Gomez Marmolejo
+ *
+ * This file is part of the Zet processor. This processor is free
+ * hardware; you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by the Free Software
+ * Foundation; either version 3, or (at your option) any later version.
+ *
+ * Zet is distrubuted 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 Zet; see the file COPYING. If not, see
+ * .
+ */
+
+`timescale 1ns/10ps
+
+module rotate (
+ input [15:0] x,
+ input [ 4:0] y,
+ input [ 1:0] func, // 00: ror, 01: rol, 10: rcr, 11: rcl
+ input cfi,
+ input word_op,
+ output [15:0] out,
+ output cfo,
+ input ofi,
+ output ofo
+ );
+
+ // Net declarations
+ wire [4:0] ror16, rol16, rcr16, rcl16, rot16;
+ wire [3:0] ror8, rol8, rcr8, rcl8, rot8;
+ wire [7:0] out8;
+ wire [15:0] out16;
+ wire co8, co16;
+ wire unchanged;
+
+ // Module instantiation
+ rxr8 rxr8_0 (
+ .x (x[7:0]),
+ .ci (cfi),
+ .y (rot8),
+ .e (func[1]),
+ .w (out8),
+ .co (co8)
+ );
+
+ rxr16 rxr16_0 (
+ .x (x),
+ .ci (cfi),
+ .y (rot16),
+ .e (func[1]),
+ .w (out16),
+ .co (co16)
+ );
+
+ // Continuous assignments
+ assign unchanged = word_op ? (y==5'b0) : (y[3:0]==4'b0);
+ assign ror16 = { 1'b0, y[3:0] };
+ assign rol16 = { 1'b0, -y[3:0] };
+ assign ror8 = { 1'b0, y[2:0] };
+ assign rol8 = { 1'b0, -y[2:0] };
+
+ assign rcr16 = (y <= 5'd16) ? y : { 1'b0, y[3:0] - 4'b1 };
+ assign rcl16 = (y <= 5'd17) ? 5'd17 - y : 6'd34 - y;
+ assign rcr8 = y[3:0] <= 4'd8 ? y[3:0] : { 1'b0, y[2:0] - 3'b1 };
+ assign rcl8 = y[3:0] <= 4'd9 ? 4'd9 - y[3:0] : 5'd18 - y[3:0];
+
+ assign rot8 = func[1] ? (func[0] ? rcl8 : rcr8 )
+ : (func[0] ? rol8 : ror8 );
+ assign rot16 = func[1] ? (func[0] ? rcl16 : rcr16 )
+ : (func[0] ? rol16 : ror16 );
+
+ assign out = word_op ? out16 : { x[15:8], out8 };
+ assign cfo = unchanged ? cfi : (func[1] ? (word_op ? co16 : co8)
+ : (func[0] ? out[0]
+ : (word_op ? out[15] : out[7])));
+ // Overflow
+ assign ofo = unchanged ? ofi : (func[0] ? // left
+ (word_op ? cfo^out[15] : cfo^out[7])
+ : // right
+ (word_op ? out[15]^out[14] : out[7]^out[6]));
+endmodule
+
+module rxr16 (
+ input [15:0] x,
+ input ci,
+ input [ 4:0] y,
+ input e,
+ output reg [15:0] w,
+ output reg co
+ );
+
+ always @(x or ci or y or e)
+ case (y)
+ default: {co,w} <= {ci,x};
+ 5'd01: {co,w} <= e ? {x[0], ci, x[15:1]} : {ci, x[0], x[15:1]};
+ 5'd02: {co,w} <= e ? {x[ 1:0], ci, x[15: 2]} : {ci, x[ 1:0], x[15: 2]};
+ 5'd03: {co,w} <= e ? {x[ 2:0], ci, x[15: 3]} : {ci, x[ 2:0], x[15: 3]};
+ 5'd04: {co,w} <= e ? {x[ 3:0], ci, x[15: 4]} : {ci, x[ 3:0], x[15: 4]};
+ 5'd05: {co,w} <= e ? {x[ 4:0], ci, x[15: 5]} : {ci, x[ 4:0], x[15: 5]};
+ 5'd06: {co,w} <= e ? {x[ 5:0], ci, x[15: 6]} : {ci, x[ 5:0], x[15: 6]};
+ 5'd07: {co,w} <= e ? {x[ 6:0], ci, x[15: 7]} : {ci, x[ 6:0], x[15: 7]};
+ 5'd08: {co,w} <= e ? {x[ 7:0], ci, x[15: 8]} : {ci, x[ 7:0], x[15: 8]};
+ 5'd09: {co,w} <= e ? {x[ 8:0], ci, x[15: 9]} : {ci, x[ 8:0], x[15: 9]};
+ 5'd10: {co,w} <= e ? {x[ 9:0], ci, x[15:10]} : {ci, x[ 9:0], x[15:10]};
+ 5'd11: {co,w} <= e ? {x[10:0], ci, x[15:11]} : {ci, x[10:0], x[15:11]};
+ 5'd12: {co,w} <= e ? {x[11:0], ci, x[15:12]} : {ci, x[11:0], x[15:12]};
+ 5'd13: {co,w} <= e ? {x[12:0], ci, x[15:13]} : {ci, x[12:0], x[15:13]};
+ 5'd14: {co,w} <= e ? {x[13:0], ci, x[15:14]} : {ci, x[13:0], x[15:14]};
+ 5'd15: {co,w} <= e ? {x[14:0], ci, x[15]} : {ci, x[14:0], x[15]};
+ 5'd16: {co,w} <= {x,ci};
+ endcase
+endmodule
+
+module rxr8 (
+ input [7:0] x,
+ input ci,
+ input [3:0] y,
+ input e,
+ output reg [7:0] w,
+ output reg co
+ );
+
+ always @(x or ci or y or e)
+ case (y)
+ default: {co,w} <= {ci,x};
+ 5'd01: {co,w} <= e ? {x[0], ci, x[7:1]} : {ci, x[0], x[7:1]};
+ 5'd02: {co,w} <= e ? {x[1:0], ci, x[7:2]} : {ci, x[1:0], x[7:2]};
+ 5'd03: {co,w} <= e ? {x[2:0], ci, x[7:3]} : {ci, x[2:0], x[7:3]};
+ 5'd04: {co,w} <= e ? {x[3:0], ci, x[7:4]} : {ci, x[3:0], x[7:4]};
+ 5'd05: {co,w} <= e ? {x[4:0], ci, x[7:5]} : {ci, x[4:0], x[7:5]};
+ 5'd06: {co,w} <= e ? {x[5:0], ci, x[7:6]} : {ci, x[5:0], x[7:6]};
+ 5'd07: {co,w} <= e ? {x[6:0], ci, x[7]} : {ci, x[6:0], x[7]};
+ 5'd08: {co,w} <= {x,ci};
+ endcase
+endmodule
trunk/cores/zet/rtl/rotate.v
Property changes :
Added: svn:mergeinfo
## -0,0 +0,0 ##
Index: trunk/cores/zet/rtl/alu.v
===================================================================
--- trunk/cores/zet/rtl/alu.v (nonexistent)
+++ trunk/cores/zet/rtl/alu.v (revision 55)
@@ -0,0 +1,406 @@
+/*
+ * Copyright (c) 2008 Zeus Gomez Marmolejo
+ *
+ * This file is part of the Zet processor. This processor is free
+ * hardware; you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by the Free Software
+ * Foundation; either version 3, or (at your option) any later version.
+ *
+ * Zet is distrubuted 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 Zet; see the file COPYING. If not, see
+ * .
+ */
+
+`timescale 1ns/10ps
+
+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;
+ wire [8:0] othflags;
+ wire [19:0] oth;
+ wire [31:0] cnv, mul;
+ wire af_add, af_cnv;
+ wire cf_cnv, cf_add, cf_mul, cf_log, cf_shi, cf_rot;
+ wire of_cnv, of_add, of_mul, of_log, of_shi, of_rot;
+ 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);
+
+ conv cnv2 (
+ .x (x[15:0]),
+ .func (func),
+ .out (cnv),
+ .iflags ({afi, cfi}),
+ .oflags ({af_cnv, of_cnv, cf_cnv})
+ );
+
+ muldiv mul3 (
+ .x (x),
+ .y (y),
+ .o (mul),
+ .f (func),
+ .word_op (word_op),
+ .cfo (cf_mul),
+ .ofo (of_mul),
+ .clk (clk),
+ .exc (dexc)
+ );
+
+ bitlog log4 (x[15:0], y, log, func, cf_log, of_log);
+ shifts shi5 (x[15:0], y[4:0], shi, func[1:0], word_op, cfi, ofi, cf_shi, of_shi);
+ rotate rot6 (x[15:0], y[4:0], func[1:0], cfi, word_op, rot, cf_rot, ofi, of_rot);
+ othop oth7 (x[15:0], y, seg, off, iflags, func, word_op, oth, othflags);
+
+ mux8_16 m0(t, {8'd0, y[7:0]}, add, cnv[15:0],
+ mul[15:0], log, shi, rot, oth[15:0], out[15:0]);
+ mux8_16 m1(t, 16'd0, 16'd0, cnv[31:16], mul[31:16],
+ 16'd0, 16'd0, 16'd0, {12'b0,oth[19:16]}, out[31:16]);
+ mux8_1 a1(t, 1'b0, cf_add, cf_cnv, cf_mul, cf_log, cf_shi, cf_rot, 1'b0, cfo);
+ mux8_1 a2(t, 1'b0, af_add, af_cnv, 1'b0, 1'b0, 1'b0, afi, 1'b0, afo);
+ mux8_1 a3(t, 1'b0, of_add, of_cnv, of_mul, of_log, of_shi, of_rot, 1'b0, ofo);
+
+ // Flags
+ assign pfo = flags_unchanged ? pfi : ^~ out[7:0];
+ assign zfo = flags_unchanged ? zfi
+ : ((word_op && (t!=3'd2)) ? ~|out[15:0] : ~|out[7:0]);
+ assign sfo = flags_unchanged ? sfi
+ : ((word_op && (t!=3'd2)) ? out[15] : out[7]);
+
+ assign oflags = (t == 3'd7) ? othflags
+ : { ofo, iflags[10:8], sfo, zfo, afo, pfo, cfo };
+
+ assign ofi = iflags[11];
+ assign sfi = iflags[7];
+ assign zfi = iflags[6];
+ assign afi = iflags[4];
+ assign pfi = iflags[2];
+ assign cfi = iflags[0];
+
+ assign flags_unchanged = (t == 3'd4 && func == 3'd2
+ || t == 3'd5 && y[4:0] == 5'h0
+ || t == 3'd6);
+
+ assign div_exc = func[1] && (t==3'd3) && dexc;
+
+endmodule
+
+module addsub (
+ input [15:0] x,
+ input [15:0] y,
+ output [15:0] out,
+ input [ 2:0] f,
+ input word_op,
+ input cfi,
+ output cfo,
+ output afo,
+ output ofo
+ );
+
+ // Net declarations
+ wire [15:0] op2;
+
+ wire ci;
+ wire cfoadd;
+ wire xs, ys, os;
+
+ // Module instances
+ fulladd16 fa0 ( // We instantiate only one adder
+ .x (x), // to have less hardware
+ .y (op2),
+ .ci (ci),
+ .co (cfoadd),
+ .z (out),
+ .s (f[2])
+ );
+
+ // Assignments
+ assign op2 = f[2] ? ~y
+ : ((f[1:0]==2'b11) ? { 8'b0, y[7:0] } : y);
+ assign ci = f[2] & f[1] | f[2] & ~f[0] & ~cfi
+ | f[2] & f[0] | (f==3'b0) & cfi;
+ assign afo = f[1] ? (f[2] ? &out[3:0] : ~|out[3:0] )
+ : (x[4] ^ y[4] ^ out[4]);
+ assign cfo = f[1] ? cfi /* inc, dec */
+ : (word_op ? cfoadd : (x[8]^y[8]^out[8]));
+
+ assign xs = word_op ? x[15] : x[7];
+ assign ys = word_op ? y[15] : y[7];
+ assign os = word_op ? out[15] : out[7];
+ assign ofo = f[2] ? (~xs & ys & os | xs & ~ys & ~os)
+ : (~xs & ~ys & os | xs & ys & ~os);
+endmodule
+
+module conv (
+ input [15:0] x,
+ input [ 2:0] func,
+ output [31:0] out,
+ input [ 1:0] iflags, // afi, cfi
+ output [ 2:0] oflags // afo, ofo, cfo
+ );
+
+ // Net declarations
+ wire afi, cfi;
+ wire ofo, afo, cfo;
+ wire [15:0] aaa, aas;
+ wire [ 7:0] daa, tmpdaa, das, tmpdas;
+ wire [15:0] cbw, cwd;
+
+ wire acond, dcond;
+ wire tmpcf;
+
+ // Module instances
+ mux8_16 m0(func, cbw, aaa, aas, 16'd0,
+ cwd, {x[15:8], daa}, {x[15:8], das}, 16'd0, out[15:0]);
+
+ // Assignments
+ assign aaa = (acond ? (x + 16'h0106) : x) & 16'hff0f;
+ assign aas = (acond ? (x - 16'h0106) : x) & 16'hff0f;
+
+ assign tmpdaa = acond ? (x[7:0] + 8'h06) : x[7:0];
+ assign daa = dcond ? (tmpdaa + 8'h60) : tmpdaa;
+ assign tmpdas = acond ? (x[7:0] - 8'h06) : x[7:0];
+ assign das = dcond ? (tmpdas - 8'h60) : tmpdas;
+
+ assign cbw = { { 8{x[ 7]}}, x[7:0] };
+ assign { out[31:16], cwd } = { {16{x[15]}}, x };
+
+ assign acond = ((x[7:0] & 8'h0f) > 8'h09) | afi;
+ assign dcond = (x[7:0] > 8'h99) | cfi;
+
+ assign afi = iflags[1];
+ assign cfi = iflags[0];
+
+ assign afo = acond;
+ assign ofo = 1'b0;
+ assign tmpcf = (x[7:0] < 8'h06) | cfi;
+ assign cfo = func[2] ? (dcond ? 1'b1 : (acond & tmpcf))
+ : acond;
+
+ assign oflags = { afo, ofo, cfo };
+endmodule
+
+
+module muldiv (
+ input [31:0] x, // 16 MSb for division
+ input [15:0] y,
+ output [31:0] o,
+ input [ 2:0] f,
+ input word_op,
+ output cfo,
+ output ofo,
+ input clk,
+ output exc
+ );
+
+ // Net declarations
+ 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),
+ .a (a),
+ .b (b),
+ .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]);
+ 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 zi = f[2] ? { 26'h0, x[7:0] }
+ : (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[2] ? { 16'h0, q[7:0], s[7:0] }
+ : (f[1] ? ( word_op ? {s[15:0], q[15:0]}
+ : {16'h0, s[7:0], q[7:0]})
+ : p[31:0]);
+
+ assign ofo = f[1] ? 1'b0 : cfo;
+ assign cfo = f[1] ? 1'b0 : !(f[0] ? cfs : cfu);
+ assign cfu = word_op ? (o[31:16] == 16'h0)
+ : (o[15:8] == 8'h0);
+ assign cfs = word_op ? (o[31:16] == {16{o[15]}})
+ : (o[15:8] == {8{o[7]}});
+
+ // Exceptions
+ assign over = f[2] ? 1'b0
+ : (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 | (!f[2] & ovf) | over | mint;
+endmodule
+
+module bitlog(x, y, out, func, cfo, ofo);
+ // IO ports
+ input [15:0] x, y;
+ input [2:0] func;
+ output [15:0] out;
+ output cfo, ofo;
+
+ // Net declarations
+ wire [15:0] and_n, or_n, not_n, xor_n;
+
+ // Module instantiations
+ mux8_16 m0(func, and_n, or_n, not_n, xor_n, 16'd0, 16'd0, 16'd0, 16'd0, out);
+
+ // Assignments
+ assign and_n = x & y;
+ assign or_n = x | y;
+ assign not_n = ~x;
+ assign xor_n = x ^ y;
+
+ assign cfo = 1'b0;
+ assign ofo = 1'b0;
+endmodule
+
+//
+// This module implements the instructions shl/sal, sar, shr
+//
+
+module shifts(x, y, out, func, word_op, cfi, ofi, cfo, ofo);
+ // IO ports
+ input [15:0] x;
+ input [ 4:0] y;
+ input [1:0] func;
+ input word_op;
+ output [15:0] out;
+ output cfo, ofo;
+ input cfi, ofi;
+
+ // Net declarations
+ wire [15:0] sal, sar, shr, sal16, sar16, shr16;
+ wire [7:0] sal8, sar8, shr8;
+ wire ofo_shl, ofo_sar, ofo_shr;
+ wire cfo_sal8, cfo_sal16, cfo_sar8, cfo_sar16, cfo_shr8, cfo_shr16;
+ wire cfo16, cfo8;
+ wire unchanged;
+
+ // Module instantiations
+ mux4_16 m0(func, sal, sar, shr, 16'd0, out);
+
+ // Assignments
+ assign { cfo_sal16, sal16 } = x << y;
+ assign { sar16, cfo_sar16 } = (y > 5'd16) ? 17'h1ffff
+ : (({x,1'b0} >> y) | (x[15] ? (17'h1ffff << (17 - y))
+ : 17'h0));
+ assign { shr16, cfo_shr16 } = ({x,1'b0} >> y);
+
+ assign { cfo_sal8, sal8 } = x[7:0] << y;
+ assign { sar8, cfo_sar8 } = (y > 5'd8) ? 9'h1ff
+ : (({x[7:0],1'b0} >> y) | (x[7] ? (9'h1ff << (9 - y))
+ : 9'h0));
+ assign { shr8, cfo_shr8 } = ({x[7:0],1'b0} >> y);
+
+ assign sal = word_op ? sal16 : { 8'd0, sal8 };
+ assign shr = word_op ? shr16 : { 8'd0, shr8 };
+ assign sar = word_op ? sar16 : { {8{sar8[7]}}, sar8 };
+
+ assign ofo = unchanged ? ofi
+ : (func[1] ? ofo_shr : (func[0] ? ofo_sar : ofo_shl));
+ assign cfo16 = func[1] ? cfo_shr16
+ : (func[0] ? cfo_sar16 : cfo_sal16);
+ assign cfo8 = func[1] ? cfo_shr8
+ : (func[0] ? cfo_sar8 : cfo_sal8);
+ assign cfo = unchanged ? cfi : (word_op ? cfo16 : cfo8);
+ assign ofo_shl = word_op ? (out[15] != cfo) : (out[7] != cfo);
+ assign ofo_sar = 1'b0;
+ assign ofo_shr = word_op ? x[15] : x[7];
+
+ assign unchanged = word_op ? (y==5'b0) : (y[3:0]==4'b0);
+endmodule
+
+module othop (x, y, seg, off, iflags, func, word_op, out, oflags);
+ // IO ports
+ input [15:0] x, y, off, seg, iflags;
+ input [2:0] func;
+ input word_op;
+ output [19:0] out;
+ output [8:0] oflags;
+
+ // Net declarations
+ wire [15:0] deff, deff2, outf, clcm, setf, intf, strf;
+ wire [19:0] dcmp, dcmp2;
+ wire dfi;
+
+ // Module instantiations
+ mux8_16 m0(func, dcmp[15:0], dcmp2[15:0], deff, outf, clcm, setf,
+ intf, strf, out[15:0]);
+ assign out[19:16] = func ? dcmp2[19:16] : dcmp[19:16];
+
+ // Assignments
+ assign dcmp = (seg << 4) + deff;
+ assign dcmp2 = (seg << 4) + deff2;
+ assign deff = x + y + off;
+ assign deff2 = x + y + off + 16'd2;
+ assign outf = y;
+ assign clcm = y[2] ? (y[1] ? /* -1: clc */ {iflags[15:1], 1'b0}
+ : /* 4: cld */ {iflags[15:11], 1'b0, iflags[9:0]})
+ : (y[1] ? /* 2: cli */ {iflags[15:10], 1'b0, iflags[8:0]}
+ : /* 0: cmc */ {iflags[15:1], ~iflags[0]});
+ assign setf = y[2] ? (y[1] ? /* -1: stc */ {iflags[15:1], 1'b1}
+ : /* 4: std */ {iflags[15:11], 1'b1, iflags[9:0]})
+ : (y[1] ? /* 2: sti */ {iflags[15:10], 1'b1, iflags[8:0]}
+ : /* 0: outf */ iflags);
+
+ assign intf = {iflags[15:10], 2'b0, iflags[7:0]};
+ assign dfi = iflags[10];
+ assign strf = dfi ? (x - y) : (x + y);
+
+ assign oflags = word_op ? { out[11:6], out[4], out[2], out[0] }
+ : { iflags[11:8], out[7:6], out[4], out[2], out[0] };
+endmodule
trunk/cores/zet/rtl/alu.v
Property changes :
Added: svn:mergeinfo
## -0,0 +0,0 ##
Index: trunk/cores/zet/rtl/exec.v
===================================================================
--- trunk/cores/zet/rtl/exec.v (nonexistent)
+++ trunk/cores/zet/rtl/exec.v (revision 55)
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2008 Zeus Gomez Marmolejo
+ *
+ * This file is part of the Zet processor. This processor is free
+ * hardware; you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by the Free Software
+ * Foundation; either version 3, or (at your option) any later version.
+ *
+ * Zet is distrubuted 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 Zet; see the file COPYING. If not, see
+ * .
+ */
+
+`timescale 1ns/10ps
+
+`include "defines.v"
+
+module exec (
+ // IO Ports
+`ifdef DEBUG
+ output [15:0] x,
+ output [15:0] y,
+ output [15:0] aluo,
+ output [15:0] ax,
+ output [15:0] dx,
+ output [15:0] bp,
+ output [15:0] si,
+ output [15:0] es,
+ output [15:0] c,
+ output [ 3:0] addr_c,
+ output [15:0] omemalu,
+ output [ 3:0] addr_d,
+ output [ 8:0] flags,
+`endif
+ input [`IR_SIZE-1:0] ir,
+ input [15:0] off,
+ input [15:0] imm,
+ output [15:0] cs,
+ output [15:0] ip,
+ output of,
+ output zf,
+ output cx_zero,
+ input clk,
+ input rst,
+ input [15:0] memout,
+
+ output [15:0] wr_data,
+ output [19:0] addr,
+ output we,
+ output m_io,
+ output byteop,
+ input block,
+ output div_exc,
+ input wrip0,
+
+ output ifl
+ );
+
+ // Net declarations
+`ifndef DEBUG
+ wire [15:0] c;
+ wire [15:0] omemalu;
+ wire [ 3:0] addr_c;
+ wire [ 3:0] addr_d;
+ wire [8:0] flags;
+`endif
+ wire [15:0] a, b, s, alu_iflags, bus_b;
+ wire [31:0] aluout;
+ wire [3:0] addr_a, addr_b;
+ wire [2:0] t, func;
+ wire [1:0] addr_s;
+ wire wrfl, high, memalu, r_byte, c_byte;
+ wire wr, wr_reg;
+ wire wr_cnd;
+ wire jmp;
+ wire b_imm;
+ wire [8:0] iflags, oflags;
+ wire [4:0] logic_flags;
+ 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,
+ alu_word, s, off, clk, dive);
+ regfile reg0 (
+`ifdef DEBUG
+ ax, dx, bp, si, es,
+`endif
+ a, b, c, cs, ip, {aluout[31:16], omemalu}, s, flags, wr_reg, wrfl,
+ 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
+ assign addr_s = ir[1:0];
+ assign addr_a = ir[5:2];
+ assign addr_b = ir[9:6];
+ assign addr_c = ir[13:10];
+ assign addr_d = ir[17:14];
+ assign wrfl = ir[18];
+ assign we = ir[19];
+ assign wr = ir[20];
+ assign wr_cnd = ir[21];
+ assign high = ir[22];
+ assign t = ir[25:23];
+ assign func = ir[28:26];
+ assign byteop = ir[29];
+ assign memalu = ir[30];
+ assign m_io = ir[32];
+ assign b_imm = ir[33];
+ assign r_byte = ir[34];
+ assign c_byte = ir[35];
+
+ assign omemalu = memalu ? aluout[15:0] : memout;
+ assign bus_b = b_imm ? imm : b;
+
+ assign addr = aluout[19:0];
+ assign wr_data = c;
+ assign wr_reg = (wr | (jmp & wr_cnd)) && !block && !div_exc;
+ assign wr_high = high && !block && !div_exc;
+ assign of = flags[8];
+ assign ifl = flags[6];
+ assign zf = flags[3];
+
+ assign iflags = oflags;
+ assign alu_iflags = { 4'b0, flags[8:3], 1'b0, flags[2], 1'b0, flags[1],
+ 1'b1, flags[0] };
+ assign logic_flags = { flags[8], flags[4], flags[3], flags[1], flags[0] };
+
+ 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;
+ assign y = bus_b;
+ assign aluo = aluout;
+`endif
+endmodule
trunk/cores/zet/rtl/exec.v
Property changes :
Added: svn:mergeinfo
## -0,0 +0,0 ##
Index: trunk/cores/zet/rtl/cpu.v
===================================================================
--- trunk/cores/zet/rtl/cpu.v (nonexistent)
+++ trunk/cores/zet/rtl/cpu.v (revision 55)
@@ -0,0 +1,312 @@
+/*
+ * Copyright (c) 2008 Zeus Gomez Marmolejo
+ *
+ * This file is part of the Zet processor. This processor is free
+ * hardware; you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by the Free Software
+ * Foundation; either version 3, or (at your option) any later version.
+ *
+ * Zet is distrubuted 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 Zet; see the file COPYING. If not, see
+ * .
+ */
+
+`timescale 1ns/10ps
+
+`include "defines.v"
+
+module cpu (
+`ifdef DEBUG
+ output [15:0] cs,
+ output [15:0] ip,
+ output [ 2:0] state,
+ output [ 2:0] next_state,
+ output [ 5:0] iralu,
+ output [15:0] x,
+ output [15:0] y,
+ output [15:0] imm,
+ output [15:0] aluo,
+ output [15:0] ax,
+ output [15:0] dx,
+ output [15:0] bp,
+ output [15:0] si,
+ output [15:0] es,
+ input dbg_block,
+ output [15:0] c,
+ output [ 3:0] addr_c,
+ output [15:0] cpu_dat_o,
+ output [15:0] d,
+ output [ 3:0] addr_d,
+ output byte_exec,
+ output [ 8:0] flags,
+ output end_seq,
+ output ext_int,
+ output cpu_block,
+`endif
+
+ // Wishbone master interface
+ input wb_clk_i,
+ input wb_rst_i,
+ input [15:0] wb_dat_i,
+ output [15:0] wb_dat_o,
+ output [19:1] wb_adr_o,
+ output wb_we_o,
+ output wb_tga_o, // io/mem
+ output [ 1:0] wb_sel_o,
+ output wb_stb_o,
+ output wb_cyc_o,
+ input wb_ack_i,
+ input wb_tgc_i, // intr
+ output wb_tgc_o // inta
+ );
+
+ // Net declarations
+`ifndef DEBUG
+ wire [15:0] cs, ip;
+ wire [15:0] imm;
+ wire [15:0] cpu_dat_o;
+ wire byte_exec;
+ wire cpu_block;
+`endif
+ wire [`IR_SIZE-1:0] ir;
+ wire [15:0] off;
+
+ wire [19:0] addr_exec, addr_fetch;
+ wire byte_fetch, fetch_or_exec;
+ wire of, zf, cx_zero;
+ wire div_exc;
+ wire wr_ip0;
+ wire ifl;
+
+ wire cpu_byte_o;
+ wire cpu_m_io;
+ wire [19:0] cpu_adr_o;
+ wire wb_block;
+ wire [15:0] cpu_dat_i;
+ wire cpu_we_o;
+ wire [15:0] iid_dat_i;
+
+ // Module instantiations
+ fetch fetch0 (
+`ifdef DEBUG
+ .state (state),
+ .next_state (next_state),
+ .ext_int (ext_int),
+ .end_seq (end_seq),
+`endif
+ .clk (wb_clk_i),
+ .rst (wb_rst_i),
+ .cs (cs),
+ .ip (ip),
+ .of (of),
+ .zf (zf),
+ .data (cpu_dat_i),
+ .ir (ir),
+ .off (off),
+ .imm (imm),
+ .pc (addr_fetch),
+
+ .cx_zero (cx_zero),
+ .bytefetch (byte_fetch),
+ .fetch_or_exec (fetch_or_exec),
+ .block (cpu_block),
+ .div_exc (div_exc),
+
+ .wr_ip0 (wr_ip0),
+
+ .intr (wb_tgc_i),
+ .ifl (ifl),
+ .inta (wb_tgc_o)
+ );
+
+ exec exec0 (
+`ifdef DEBUG
+ .x (x),
+ .y (y),
+ .aluo (aluo),
+ .ax (ax),
+ .dx (dx),
+ .bp (bp),
+ .si (si),
+ .es (es),
+ .c (c),
+ .addr_c (addr_c),
+ .omemalu (d),
+ .addr_d (addr_d),
+ .flags (flags),
+`endif
+ .ir (ir),
+ .off (off),
+ .imm (imm),
+ .cs (cs),
+ .ip (ip),
+ .of (of),
+ .zf (zf),
+ .cx_zero (cx_zero),
+ .clk (wb_clk_i),
+ .rst (wb_rst_i),
+ .memout (iid_dat_i),
+ .wr_data (cpu_dat_o),
+ .addr (addr_exec),
+ .we (cpu_we_o),
+ .m_io (cpu_m_io),
+ .byteop (byte_exec),
+ .block (cpu_block),
+ .div_exc (div_exc),
+ .wrip0 (wr_ip0),
+
+ .ifl (ifl)
+ );
+
+ wb_master wm0 (
+ .cpu_byte_o (cpu_byte_o),
+ .cpu_memop (ir[`MEM_OP]),
+ .cpu_m_io (cpu_m_io),
+ .cpu_adr_o (cpu_adr_o),
+ .cpu_block (wb_block),
+ .cpu_dat_i (cpu_dat_i),
+ .cpu_dat_o (cpu_dat_o),
+ .cpu_we_o (cpu_we_o),
+
+ .wb_clk_i (wb_clk_i),
+ .wb_rst_i (wb_rst_i),
+ .wb_dat_i (wb_dat_i),
+ .wb_dat_o (wb_dat_o),
+ .wb_adr_o (wb_adr_o),
+ .wb_we_o (wb_we_o),
+ .wb_tga_o (wb_tga_o),
+ .wb_sel_o (wb_sel_o),
+ .wb_stb_o (wb_stb_o),
+ .wb_cyc_o (wb_cyc_o),
+ .wb_ack_i (wb_ack_i)
+ );
+
+ // Assignments
+ assign cpu_adr_o = fetch_or_exec ? addr_exec : addr_fetch;
+ assign cpu_byte_o = fetch_or_exec ? byte_exec : byte_fetch;
+ assign iid_dat_i = wb_tgc_o ? wb_dat_i : cpu_dat_i;
+
+`ifdef DEBUG
+ assign iralu = ir[28:23];
+ assign cpu_block = wb_block | dbg_block;
+`else
+ assign cpu_block = wb_block;
+`endif
+endmodule
+
+module wb_master (
+ input cpu_byte_o,
+ input cpu_memop,
+ input cpu_m_io,
+ input [19:0] cpu_adr_o,
+ output reg cpu_block,
+ output reg [15:0] cpu_dat_i,
+ input [15:0] cpu_dat_o,
+ input cpu_we_o,
+
+ input wb_clk_i,
+ input wb_rst_i,
+ input [15:0] wb_dat_i,
+ output [15:0] wb_dat_o,
+ output reg [19:1] wb_adr_o,
+ output wb_we_o,
+ output wb_tga_o,
+ output reg [ 1:0] wb_sel_o,
+ output reg wb_stb_o,
+ output reg wb_cyc_o,
+ input wb_ack_i
+ );
+
+ // Register and nets declarations
+ reg [ 1:0] cs; // current state
+ reg [ 1:0] ns; // next state
+
+ wire op; // in an operation
+ wire odd_word; // unaligned word
+ wire a0; // address 0 pin
+ wire [15:0] blw; // low byte (sign extended)
+ wire [15:0] bhw; // high byte (sign extended)
+ wire [19:1] adr1; // next address (for unaligned acc)
+ wire [ 1:0] sel_o; // bus byte select
+
+ // Declare the symbolic names for states
+ localparam [1:0]
+ IDLE = 2'd0,
+ stb1_lo = 2'd1,
+ stb2_hi = 2'd2;
+
+ // Assignments
+ assign op = (cpu_memop | cpu_m_io);
+ assign odd_word = (cpu_adr_o[0] & !cpu_byte_o);
+ assign a0 = cpu_adr_o[0];
+ assign blw = { {8{wb_dat_i[7]}}, wb_dat_i[7:0] };
+ assign bhw = { {8{wb_dat_i[15]}}, wb_dat_i[15:8] };
+ assign adr1 = a0 ? (cpu_adr_o[19:1] + 1'b1)
+ : cpu_adr_o[19:1];
+ assign wb_dat_o = a0 ? { cpu_dat_o[7:0], cpu_dat_o[15:8] }
+ : cpu_dat_o;
+ assign wb_we_o = cpu_we_o;
+ assign wb_tga_o = cpu_m_io;
+ assign sel_o = a0 ? 2'b10 : (cpu_byte_o ? 2'b01 : 2'b11);
+
+ // Behaviour
+ // cpu_dat_i
+ always @(posedge wb_clk_i)
+ cpu_dat_i <= (cs == IDLE) ?
+ (wb_ack_i ?
+ (a0 ? bhw : (cpu_byte_o ? blw : wb_dat_i))
+ : cpu_dat_i)
+ : ((cs == stb1_lo && wb_ack_i) ?
+ { wb_dat_i[7:0], cpu_dat_i[7:0] }
+ : cpu_dat_i);
+
+ // outputs setup
+ always @(*)
+ case (cs)
+ default:
+ begin
+ cpu_block <= op;
+ wb_adr_o <= cpu_adr_o[19:1];
+ wb_sel_o <= sel_o;
+ wb_stb_o <= op;
+ wb_cyc_o <= op;
+ end
+ stb1_lo:
+ begin
+ cpu_block <= 1'b1;
+ wb_adr_o <= adr1;
+ wb_sel_o <= 2'b01;
+ wb_stb_o <= 1'b1;
+ wb_cyc_o <= 1'b1;
+ end
+ stb2_hi:
+ begin
+ cpu_block <= wb_ack_i;
+ wb_adr_o <= adr1;
+ wb_sel_o <= 2'b01;
+ wb_stb_o <= 1'b0;
+ wb_cyc_o <= 1'b0;
+ end
+ endcase
+
+ // state machine
+ // cs - current state
+ always @(posedge wb_clk_i)
+ cs <= wb_rst_i ? IDLE : ns;
+
+ // ns - next state
+ always @(*)
+ case (cs)
+ default: ns <= wb_ack_i ?
+ (op ? (odd_word ? stb1_lo : stb2_hi) : IDLE)
+ : IDLE;
+ stb1_lo: ns <= wb_ack_i ? stb2_hi : stb1_lo;
+ stb2_hi: ns <= wb_ack_i ? stb2_hi : IDLE;
+ endcase
+
+endmodule
trunk/cores/zet/rtl/cpu.v
Property changes :
Added: svn:mergeinfo
## -0,0 +0,0 ##
Index: trunk/cores/zet/rtl/fetch.v
===================================================================
--- trunk/cores/zet/rtl/fetch.v (nonexistent)
+++ trunk/cores/zet/rtl/fetch.v (revision 55)
@@ -0,0 +1,1736 @@
+/*
+ * Copyright (c) 2008 Zeus Gomez Marmolejo
+ *
+ * This file is part of the Zet processor. This processor is free
+ * hardware; you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by the Free Software
+ * Foundation; either version 3, or (at your option) any later version.
+ *
+ * Zet is distrubuted 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 Zet; see the file COPYING. If not, see
+ * .
+ */
+
+`timescale 1ns/10ps
+
+`include "defines.v"
+
+module fetch (
+`ifdef DEBUG
+ output reg [2:0] state,
+ output [2:0] next_state,
+ output ext_int,
+ output end_seq,
+`endif
+ input clk,
+ input rst,
+ input [15:0] cs,
+ input [15:0] ip,
+ input of,
+ input zf,
+ input cx_zero,
+ input [15:0] data,
+ output [`IR_SIZE-1:0] ir,
+ output [15:0] off,
+ output [15:0] imm,
+ output [19:0] pc,
+ output bytefetch,
+ output fetch_or_exec,
+ input block,
+ input div_exc,
+ output wr_ip0,
+ input intr,
+ input ifl,
+ output inta
+ );
+
+ // Registers, nets and parameters
+ parameter opcod_st = 3'h0;
+ parameter modrm_st = 3'h1;
+ parameter offse_st = 3'h2;
+ parameter immed_st = 3'h3;
+ parameter execu_st = 3'h4;
+
+`ifndef DEBUG
+ reg [2:0] state;
+ wire [2:0] next_state;
+ wire end_seq;
+ wire ext_int;
+`endif
+
+ wire [`IR_SIZE-1:0] rom_ir;
+ wire [7:0] opcode, modrm;
+ wire exec_st;
+ wire [15:0] imm_d;
+ wire prefix, repz_pr, sovr_pr;
+ wire next_in_opco, next_in_exec;
+ wire need_modrm, need_off, need_imm, off_size, imm_size;
+
+ reg [7:0] opcode_l, modrm_l;
+ reg [15:0] off_l, imm_l;
+ reg [1:0] pref_l;
+ reg [2:0] sop_l;
+
+ // Module instantiation
+ 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, sop_l, intr, ifl,
+ inta, ext_int, pref_l[1]);
+ next_or_not nn0(pref_l, opcode[7:1], cx_zero, zf, ext_int, 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, div_exc,
+ intr, ifl, next_state);
+
+ // Assignments
+ assign pc = (cs << 4) + ip;
+
+ assign ir = (state == execu_st) ? rom_ir : `ADD_IP;
+ assign opcode = (state == opcod_st) ? data[7:0] : opcode_l;
+ assign modrm = (state == modrm_st) ? data[7:0] : modrm_l;
+ assign fetch_or_exec = (state == execu_st);
+ 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
+ | (state == immed_st) & imm_size) ? 16'd2
+ : 16'd1);
+ assign wr_ip0 = (state == opcod_st) && !pref_l[1] && !sop_l[2];
+
+ assign sovr_pr = (opcode[7:5]==3'b001 && opcode[2:0]==3'b110);
+ assign repz_pr = (opcode[7:1]==7'b1111_001);
+ assign prefix = sovr_pr || repz_pr;
+
+ // Behaviour
+ always @(posedge clk)
+ if (rst)
+ begin
+ state <= execu_st;
+ opcode_l <= `OP_NOP;
+ end
+ else if (!block)
+ case (next_state)
+ default: // opcode or prefix
+ begin
+ case (state)
+ opcod_st:
+ begin // There has been a prefix
+ pref_l <= repz_pr ? { 1'b1, opcode[0] } : pref_l;
+ sop_l <= sovr_pr ? { 1'b1, opcode[4:3] } : sop_l;
+ end
+ default: begin pref_l <= 2'b0; sop_l <= 3'b0; end
+ endcase
+ state <= opcod_st;
+ off_l <= 16'd0;
+ modrm_l <= 8'b0000_0110;
+ end
+
+ modrm_st: // modrm
+ begin
+ opcode_l <= data[7:0];
+ state <= modrm_st;
+ end
+
+ offse_st: // offset
+ begin
+ case (state)
+ opcod_st: opcode_l <= data[7:0];
+ default: modrm_l <= data[7:0];
+ endcase
+ state <= offse_st;
+ end
+
+ immed_st: // immediate
+ begin
+ case (state)
+ opcod_st: opcode_l <= data[7:0];
+ modrm_st: modrm_l <= data[7:0];
+ default: off_l <= data;
+ endcase
+ state <= immed_st;
+ end
+
+ execu_st: // execute
+ begin
+ case (state)
+ opcod_st: opcode_l <= data[7:0];
+ modrm_st: modrm_l <= data[7:0];
+ offse_st: off_l <= data;
+ immed_st: imm_l <= data;
+ endcase
+ state <= execu_st;
+ end
+ endcase
+endmodule
+
+module nstate (
+ input [2:0] state,
+ input prefix,
+ input need_modrm,
+ input need_off,
+ input need_imm,
+ input end_seq,
+ input [5:0] ftype,
+ input of,
+ input next_in_opco,
+ input next_in_exec,
+ input block,
+ input div_exc,
+ input intr,
+ input ifl,
+ output [2:0] next_state
+ );
+
+ // Net declarations
+ parameter opcod_st = 3'h0;
+ parameter modrm_st = 3'h1;
+ parameter offse_st = 3'h2;
+ parameter immed_st = 3'h3;
+ parameter execu_st = 3'h4;
+ wire into, end_instr, end_into;
+ wire [2:0] n_state;
+ wire intr_ifl;
+
+ // Assignments
+ assign into = (ftype==6'b111_010);
+ assign end_into = into ? ~of : end_seq;
+ assign end_instr = !div_exc && !intr_ifl && end_into && !next_in_exec;
+ assign intr_ifl = intr & ifl;
+
+ assign n_state = (state == opcod_st) ? (prefix ? opcod_st
+ : (next_in_opco ? opcod_st
+ : (need_modrm ? modrm_st
+ : (need_off ? offse_st
+ : (need_imm ? immed_st : execu_st)))))
+ : (state == modrm_st) ? (need_off ? offse_st
+ : (need_imm ? immed_st : execu_st))
+ : (state == offse_st) ? (need_imm ? immed_st : execu_st)
+ : (state == immed_st) ? (execu_st)
+ /* state == execu_st */ : (end_instr ? opcod_st : execu_st);
+
+ assign next_state = block ? state : n_state;
+endmodule
+
+module next_or_not (
+ input [1:0] prefix,
+ input [7:1] opcode,
+ input cx_zero,
+ input zf,
+ input ext_int,
+ output next_in_opco,
+ output next_in_exec
+ );
+
+ // Net declarations
+ wire exit_z, cmp_sca, exit_rep, valid_ops;
+
+ // Assignments
+ assign cmp_sca = opcode[2] & opcode[1];
+ assign exit_z = prefix[0] ? /* repz */ (cmp_sca ? ~zf : 1'b0 )
+ : /* repnz */ (cmp_sca ? zf : 1'b0 );
+ assign exit_rep = cx_zero | exit_z;
+ assign valid_ops = (opcode[7:1]==7'b1010_010 // movs
+ || opcode[7:1]==7'b1010_011 // cmps
+ || opcode[7:1]==7'b1010_101 // stos
+ || opcode[7:1]==7'b1010_110 // lods
+ || opcode[7:1]==7'b1010_111); // scas
+ assign next_in_exec = prefix[1] && valid_ops && !exit_rep && !ext_int;
+ assign next_in_opco = prefix[1] && valid_ops && cx_zero;
+endmodule
+
+module decode (
+ input [7:0] opcode,
+ input [7:0] modrm,
+ input [15:0] off_i,
+ input [15:0] imm_i,
+ input rep,
+ input clk,
+ input rst,
+ input block,
+ input exec_st,
+ input div_exc,
+
+ output need_modrm,
+ output need_off,
+ output need_imm,
+ output off_size,
+ output imm_size,
+
+ output [`IR_SIZE-1:0] ir,
+ output [15:0] off_o,
+ output [15:0] imm_o,
+ output end_seq,
+
+ input [2:0] sop_l,
+
+ input intr,
+ input ifl,
+ output reg inta,
+ output reg ext_int,
+ input repz_pr
+ );
+
+ // Net declarations
+ wire [`SEQ_ADDR_WIDTH-1:0] base_addr, seq_addr;
+ wire [`SEQ_DATA_WIDTH-2:0] micro_addr;
+ wire [3:0] src, dst, base, index;
+ wire [1:0] seg;
+ reg [`SEQ_ADDR_WIDTH-1:0] seq;
+ reg dive;
+ reg old_ext_int;
+
+ // Module instantiations
+ opcode_deco opcode_deco0 (opcode, modrm, rep, sop_l, base_addr, need_modrm,
+ need_off, need_imm, off_size, imm_size, src, dst,
+ base, index, seg);
+ seq_rom seq_rom0 (seq_addr, {end_seq, micro_addr});
+ micro_data mdata0 (micro_addr, off_i, imm_i, src, dst, base, index, seg,
+ ir, off_o, imm_o);
+
+ // Assignments
+ assign seq_addr = (dive ? `INTD
+ : (ext_int ? (repz_pr ? `EINTP : `EINT) : 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));
+
+ // ext_int
+ always @(posedge clk)
+ if (rst) ext_int <= 1'b0;
+ else ext_int <= block ? ext_int
+ : ((intr & ifl & exec_st & end_seq) ? 1'b1
+ : (ext_int ? !end_seq : 1'b0));
+
+ // old_ext_int
+ always @(posedge clk) old_ext_int <= rst ? 1'b0 : ext_int;
+
+ // inta
+ always @(posedge clk)
+ inta <= rst ? 1'b0 : (!old_ext_int & ext_int);
+
+endmodule
+
+module opcode_deco (
+ input [7:0] op,
+ input [7:0] modrm,
+ input rep,
+ input [2:0] sovr_pr,
+
+ output reg [`SEQ_ADDR_WIDTH-1:0] seq_addr,
+ output reg need_modrm,
+ output reg need_off,
+ output reg need_imm,
+ output off_size,
+ output reg imm_size,
+
+ output reg [3:0] src,
+ output reg [3:0] dst,
+ output [3:0] base,
+ output [3:0] index,
+ output [1:0] seg
+ );
+
+ // Net declarations
+ wire [1:0] mod;
+ wire [2:0] regm;
+ wire [2:0] rm;
+ wire d, b, sm, dm;
+ wire off_size_mod, need_off_mod;
+ wire [2:0] srcm, dstm;
+ wire off_size_from_mod;
+
+ // Module instantiations
+ memory_regs mr(rm, mod, sovr_pr, base, index, seg);
+
+ // Assignments
+ assign mod = modrm[7:6];
+ assign regm = modrm[5:3];
+ assign rm = modrm[2:0];
+ assign d = op[1];
+ assign dstm = d ? regm : rm;
+ assign sm = d & (mod != 2'b11);
+ assign dm = ~d & (mod != 2'b11);
+ assign srcm = d ? rm : regm;
+ assign b = ~op[0];
+ assign off_size_mod = (base == 4'b1100 && index == 4'b1100) ? 1'b1 : mod[1];
+ assign need_off_mod = (base == 4'b1100 && index == 4'b1100) || ^mod;
+ assign off_size_from_mod = !op[7] | (!op[5] & !op[4]) | (op[6] & op[4]);
+ assign off_size = !off_size_from_mod | off_size_mod;
+
+ // Behaviour
+ always @(op or dm or b or need_off_mod or srcm or sm or dstm
+ or mod or rm or regm or rep or modrm)
+ casex (op)
+ 8'b0000_000x: // add r->r, r->m
+ begin
+ seq_addr <= (mod==2'b11) ? (b ? `ADDRRB : `ADDRRW)
+ : (b ? `ADDRMB : `ADDRMW);
+ need_modrm <= 1'b1;
+ need_off <= need_off_mod;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ dst <= { 1'b0, dstm };
+ src <= { 1'b0, srcm };
+ end
+
+ 8'b0000_001x: // add r->r, m->r
+ begin
+ seq_addr <= (mod==2'b11) ? (b ? `ADDRRB : `ADDRRW)
+ : (b ? `ADDMRB : `ADDMRW);
+ need_modrm <= 1'b1;
+ need_off <= need_off_mod;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ dst <= { 1'b0, dstm };
+ src <= { 1'b0, srcm };
+ end
+
+ 8'b0000_010x: // add i->r
+ begin
+ seq_addr <= b ? `ADDIRB : `ADDIRW;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b1;
+ imm_size <= ~b;
+ dst <= 4'b0;
+ src <= 4'b0;
+ end
+
+ 8'b000x_x110: // push seg
+ begin
+ seq_addr <= `PUSHR;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ src <= { 2'b10, op[4:3] };
+ dst <= 4'b0;
+ end
+
+ 8'b0000_100x: // or r->r, r->m
+ begin
+ seq_addr <= (mod==2'b11) ? (b ? `ORRRB : `ORRRW)
+ : (b ? `ORRMB : `ORRMW);
+ need_modrm <= 1'b1;
+ need_off <= need_off_mod;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ dst <= { 1'b0, dstm };
+ src <= { 1'b0, srcm };
+ end
+
+ 8'b0000_101x: // or r->r, m->r
+ begin
+ seq_addr <= (mod==2'b11) ? (b ? `ORRRB : `ORRRW)
+ : (b ? `ORMRB : `ORMRW);
+ need_modrm <= 1'b1;
+ need_off <= need_off_mod;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ dst <= { 1'b0, dstm };
+ src <= { 1'b0, srcm };
+ end
+
+ 8'b0000_110x: // or i->r
+ begin
+ seq_addr <= b ? `ORIRB : `ORIRW;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b1;
+ imm_size <= ~b;
+ dst <= 4'b0;
+ src <= 4'b0;
+ end
+
+ 8'b000x_x111: // pop seg
+ begin
+ seq_addr <= `POPR;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= { 2'b10, op[4:3] };
+ end
+
+ 8'b0001_000x: // adc r->r, r->m
+ begin
+ seq_addr <= (mod==2'b11) ? (b ? `ADCRRB : `ADCRRW)
+ : (b ? `ADCRMB : `ADCRMW);
+ need_modrm <= 1'b1;
+ need_off <= need_off_mod;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ dst <= { 1'b0, dstm };
+ src <= { 1'b0, srcm };
+ end
+
+ 8'b0001_001x: // adc r->r, m->r
+ begin
+ seq_addr <= (mod==2'b11) ? (b ? `ADCRRB : `ADCRRW)
+ : (b ? `ADCMRB : `ADCMRW);
+ need_modrm <= 1'b1;
+ need_off <= need_off_mod;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ dst <= { 1'b0, dstm };
+ src <= { 1'b0, srcm };
+ end
+
+ 8'b0001_010x: // adc i->r
+ begin
+ seq_addr <= b ? `ADCIRB : `ADCIRW;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b1;
+ imm_size <= ~b;
+ dst <= 4'b0;
+ src <= 4'b0;
+ end
+
+ 8'b0001_100x: // sbb r->r, r->m
+ begin
+ seq_addr <= (mod==2'b11) ? (b ? `SBBRRB : `SBBRRW)
+ : (b ? `SBBRMB : `SBBRMW);
+ need_modrm <= 1'b1;
+ need_off <= need_off_mod;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ dst <= { 1'b0, dstm };
+ src <= { 1'b0, srcm };
+ end
+
+ 8'b0001_101x: // sbb r->r, m->r
+ begin
+ seq_addr <= (mod==2'b11) ? (b ? `SBBRRB : `SBBRRW)
+ : (b ? `SBBMRB : `SBBMRW);
+ need_modrm <= 1'b1;
+ need_off <= need_off_mod;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ dst <= { 1'b0, dstm };
+ src <= { 1'b0, srcm };
+ end
+
+ 8'b0001_110x: // sbb i->r
+ begin
+ seq_addr <= b ? `SBBIRB : `SBBIRW;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b1;
+ imm_size <= ~b;
+ dst <= 4'b0;
+ src <= 4'b0;
+ end
+
+ 8'b0010_000x: // and r->r, r->m
+ begin
+ seq_addr <= (mod==2'b11) ? (b ? `ANDRRB : `ANDRRW)
+ : (b ? `ANDRMB : `ANDRMW);
+ need_modrm <= 1'b1;
+ need_off <= need_off_mod;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ dst <= { 1'b0, dstm };
+ src <= { 1'b0, srcm };
+ end
+
+ 8'b0010_001x: // and r->r, m->r
+ begin
+ seq_addr <= (mod==2'b11) ? (b ? `ANDRRB : `ANDRRW)
+ : (b ? `ANDMRB : `ANDMRW);
+ need_modrm <= 1'b1;
+ need_off <= need_off_mod;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ dst <= { 1'b0, dstm };
+ src <= { 1'b0, srcm };
+ end
+
+ 8'b0010_010x: // and i->r
+ begin
+ seq_addr <= b ? `ANDIRB : `ANDIRW;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b1;
+ imm_size <= ~b;
+ dst <= 4'b0;
+ src <= 4'b0;
+ end
+
+ 8'b0010_0111: // daa
+ begin
+ seq_addr <= `DAA;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ dst <= 4'b0;
+ src <= 4'b0;
+ end
+
+ 8'b0010_100x: // sub r->r, r->m
+ begin
+ seq_addr <= (mod==2'b11) ? (b ? `SUBRRB : `SUBRRW)
+ : (b ? `SUBRMB : `SUBRMW);
+ need_modrm <= 1'b1;
+ need_off <= need_off_mod;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ dst <= { 1'b0, dstm };
+ src <= { 1'b0, srcm };
+ end
+
+ 8'b0010_101x: // sub r->r, m->r
+ begin
+ seq_addr <= (mod==2'b11) ? (b ? `SUBRRB : `SUBRRW)
+ : (b ? `SUBMRB : `SUBMRW);
+ need_modrm <= 1'b1;
+ need_off <= need_off_mod;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ dst <= { 1'b0, dstm };
+ src <= { 1'b0, srcm };
+ end
+
+ 8'b0010_110x: // sub i->r
+ begin
+ seq_addr <= b ? `SUBIRB : `SUBIRW;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b1;
+ imm_size <= ~b;
+ dst <= 4'b0;
+ src <= 4'b0;
+ end
+
+ 8'b0010_1111: // das
+ begin
+ seq_addr <= `DAS;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ dst <= 4'b0;
+ src <= 4'b0;
+ end
+
+ 8'b0011_000x: // xor r->r, r->m
+ begin
+ seq_addr <= (mod==2'b11) ? (b ? `XORRRB : `XORRRW)
+ : (b ? `XORRMB : `XORRMW);
+ need_modrm <= 1'b1;
+ need_off <= need_off_mod;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ dst <= { 1'b0, dstm };
+ src <= { 1'b0, srcm };
+ end
+
+ 8'b0011_001x: // xor r->r, m->r
+ begin
+ seq_addr <= (mod==2'b11) ? (b ? `XORRRB : `XORRRW)
+ : (b ? `XORMRB : `XORMRW);
+ need_modrm <= 1'b1;
+ need_off <= need_off_mod;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ dst <= { 1'b0, dstm };
+ src <= { 1'b0, srcm };
+ end
+
+ 8'b0011_010x: // and i->r
+ begin
+ seq_addr <= b ? `XORIRB : `XORIRW;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b1;
+ imm_size <= ~b;
+ dst <= 4'b0;
+ src <= 4'b0;
+ end
+
+ 8'b0011_0111: // aaa
+ begin
+ seq_addr <= `AAA;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ dst <= 4'b0;
+ src <= 4'b0;
+ end
+
+ 8'b0011_100x: // cmp r->r, r->m
+ begin
+ seq_addr <= (mod==2'b11) ? (b ? `CMPRRB : `CMPRRW)
+ : (b ? `CMPRMB : `CMPRMW);
+ need_modrm <= 1'b1;
+ need_off <= need_off_mod;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ dst <= { 1'b0, dstm };
+ src <= { 1'b0, srcm };
+ end
+
+ 8'b0011_101x: // cmp r->r, m->r
+ begin
+ seq_addr <= (mod==2'b11) ? (b ? `CMPRRB : `CMPRRW)
+ : (b ? `CMPMRB : `CMPMRW);
+ need_modrm <= 1'b1;
+ need_off <= need_off_mod;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ dst <= { 1'b0, dstm };
+ src <= { 1'b0, srcm };
+ end
+
+ 8'b0011_110x: // cmp i->r
+ begin
+ seq_addr <= b ? `CMPIRB : `CMPIRW;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b1;
+ imm_size <= ~b;
+ dst <= 4'b0;
+ src <= 4'b0;
+ end
+
+ 8'b0011_1111: // aas
+ begin
+ seq_addr <= `AAS;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ dst <= 4'b0;
+ src <= 4'b0;
+ end
+
+ 8'b0100_0xxx: // inc
+ begin
+ seq_addr <= `INCRW;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ dst <= 4'b0;
+ src <= { 1'b0, op[2:0] };
+ end
+
+ 8'b0100_1xxx: // dec
+ begin
+ seq_addr <= `DECRW;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ dst <= 4'b0;
+ src <= { 1'b0, op[2:0] };
+ end
+
+ 8'b0101_0xxx: // push reg
+ begin
+ seq_addr <= `PUSHR;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ src <= { 1'b0, op[2:0] };
+ dst <= 4'b0;
+ end
+
+ 8'b0101_1xxx: // pop reg
+ begin
+ seq_addr <= `POPR;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= { 1'b0, op[2:0] };
+ end
+
+ 8'b0111_xxxx: // jcc
+ begin
+ seq_addr <= `JCC;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b1;
+ imm_size <= 1'b0;
+ src <= { op[3:0] };
+ dst <= 4'b0;
+ end
+
+ 8'b1000_00xx: // and, or i->r, i->m
+ begin
+ seq_addr <= regm == 3'b111 ?
+ ((mod==2'b11) ? (b ? `CMPIRB : `CMPIRW)
+ : (b ? `CMPIMB : `CMPIMW))
+ : (regm == 3'b101 ? ((mod==2'b11) ? (b ? `SUBIRB : `SUBIRW)
+ : (b ? `SUBIMB : `SUBIMW))
+ : (regm == 3'b011 ? ((mod==2'b11) ? (b ? `SBBIRB : `SBBIRW)
+ : (b ? `SBBIMB : `SBBIMW))
+ : (regm == 3'b010 ? ((mod==2'b11) ? (b ? `ADCIRB : `ADCIRW)
+ : (b ? `ADCIMB : `ADCIMW))
+ : (regm == 3'b000 ? ((mod==2'b11) ? (b ? `ADDIRB : `ADDIRW)
+ : (b ? `ADDIMB : `ADDIMW))
+ : (regm == 3'b100 ? ((mod==2'b11) ? (b ? `ANDIRB : `ANDIRW)
+ : (b ? `ANDIMB : `ANDIMW))
+ : (regm == 3'b001 ? ((mod==2'b11) ? (b ? `ORIRB : `ORIRW)
+ : (b ? `ORIMB : `ORIMW))
+ : ((mod==2'b11) ? (b ? `XORIRB : `XORIRW)
+ : (b ? `XORIMB : `XORIMW))))))));
+ need_modrm <= 1'b1;
+ need_off <= need_off_mod;
+ need_imm <= 1'b1;
+ imm_size <= !op[1] & op[0];
+ dst <= { 1'b0, modrm[2:0] };
+ src <= 4'b0;
+ end
+
+ 8'b1000_010x: // test r->r, r->m
+ begin
+ seq_addr <= (mod==2'b11) ? (b ? `TSTRRB : `TSTRRW)
+ : (b ? `TSTMRB : `TSTMRW);
+ need_modrm <= 1'b1;
+ need_off <= need_off_mod;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ dst <= { 1'b0, srcm };
+ src <= { 1'b0, dstm };
+ end
+
+ 8'b1000_011x: // xchg
+ begin
+ seq_addr <= (mod==2'b11) ? (b ? `XCHRRB : `XCHRRW)
+ : (b ? `XCHRMB : `XCHRMW);
+ need_modrm <= 1'b1;
+ need_off <= need_off_mod;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ dst <= { 1'b0, dstm };
+ src <= { 1'b0, srcm };
+ end
+ 8'b1000_10xx: // mov: r->r, r->m, m->r
+ begin
+ if (dm) // r->m
+ begin
+ seq_addr <= b ? `MOVRMB : `MOVRMW;
+ need_off <= need_off_mod;
+ src <= { 1'b0, srcm };
+ dst <= 4'b0;
+ end
+ else if(sm) // m->r
+ begin
+ seq_addr <= b ? `MOVMRB : `MOVMRW;
+ need_off <= need_off_mod;
+ src <= 4'b0;
+ dst <= { 1'b0, dstm };
+ end
+ else // r->r
+ begin
+ seq_addr <= b ? `MOVRRB : `MOVRRW;
+ need_off <= 1'b0;
+ dst <= { 1'b0, dstm };
+ src <= { 1'b0, srcm };
+ end
+ need_imm <= 1'b0;
+ need_modrm <= 1'b1;
+ imm_size <= 1'b0;
+ end
+
+ 8'b1000_1100: // mov: s->m, s->r
+ begin
+ if (dm) // s->m
+ begin
+ seq_addr <= `MOVRMW;
+ need_off <= need_off_mod;
+ src <= { 1'b1, srcm };
+ dst <= 4'b0;
+ end
+ else // s->r
+ begin
+ seq_addr <= `MOVRRW;
+ need_off <= 1'b0;
+ src <= { 1'b1, srcm };
+ dst <= { 1'b0, dstm };
+ end
+ need_imm <= 1'b0;
+ need_modrm <= 1'b1;
+ imm_size <= 1'b0;
+ end
+
+ 8'b1000_1101: // lea
+ begin
+ seq_addr <= `LEA;
+ need_modrm <= 1'b1;
+ need_off <= need_off_mod;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ src <= { 1'b0, srcm };
+ dst <= 4'b0;
+ end
+
+ 8'b1000_1110: // mov: m->s, r->s
+ begin
+ if (sm) // m->s
+ begin
+ seq_addr <= `MOVMRW;
+ need_off <= need_off_mod;
+ src <= 4'b0;
+ dst <= { 1'b1, dstm };
+ end
+ else // r->s
+ begin
+ seq_addr <= `MOVRRW;
+ need_off <= 1'b0;
+ src <= { 1'b0, srcm };
+ dst <= { 1'b1, dstm };
+ end
+ need_modrm <= 1'b1;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ end
+
+ 8'b1000_1111: // pop mem or (pop reg non-standard)
+ begin
+ seq_addr <= (mod==2'b11) ? `POPR : `POPM;
+ need_modrm <= 1'b1;
+ need_off <= need_off_mod;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= { 1'b0, rm };
+ end
+
+ 8'b1001_0xxx: // nop, xchg acum
+ begin
+ seq_addr <= `XCHRRW;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ src <= 4'b0000;
+ dst <= { 1'b0, op[2:0] };
+ end
+
+ 8'b1001_1000: // cbw
+ begin
+ seq_addr <= `CBW;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ dst <= 4'b0;
+ src <= 4'b0;
+ end
+
+ 8'b1001_1001: // cwd
+ begin
+ seq_addr <= `CWD;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ dst <= 4'b0;
+ src <= 4'b0;
+ end
+
+ 8'b1001_1010: // call different seg
+ begin
+ seq_addr <= `CALLF;
+ need_modrm <= 1'b0;
+ need_off <= 1'b1;
+ need_imm <= 1'b1;
+ imm_size <= 1'b1;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1001_1100: // pushf
+ begin
+ seq_addr <= `PUSHF;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+
+ imm_size <= 1'b0;
+
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1001_1101: // popf
+ begin
+ seq_addr <= `POPF;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1001_1110: // sahf
+ begin
+ seq_addr <= `SAHF;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1001_1111: // lahf
+ begin
+ seq_addr <= `LAHF;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1010_000x: // mov: m->a
+ begin
+ seq_addr <= b ? `MOVMAB : `MOVMAW;
+ need_modrm <= 1'b0;
+ need_off <= 1'b1;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1010_001x: // mov: a->m
+ begin
+ seq_addr <= b ? `MOVAMB : `MOVAMW;
+ need_modrm <= 1'b0;
+ need_off <= 1'b1;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1010_010x: // movs
+ begin
+ seq_addr <= rep ? (b ? `MOVSBR : `MOVSWR) : (b ? `MOVSB : `MOVSW);
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1010_011x: // cmps
+ begin
+ seq_addr <= rep ? (b ? `CMPSBR : `CMPSWR) : (b ? `CMPSB : `CMPSW);
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1010_100x: // test i->r
+ begin
+ seq_addr <= b ? `TSTIRB : `TSTIRW;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b1;
+ imm_size <= ~b;
+ dst <= 4'b0;
+ src <= 4'b0;
+ end
+
+ 8'b1010_101x: // stos
+ begin
+ seq_addr <= rep ? (b ? `STOSBR : `STOSWR) : (b ? `STOSB : `STOSW);
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1010_110x: // lods
+ begin
+ seq_addr <= rep ? (b ? `LODSBR : `LODSWR) : (b ? `LODSB : `LODSW);
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1010_111x: // scas
+ begin
+ seq_addr <= rep ? (b ? `SCASBR : `SCASWR) : (b ? `SCASB : `SCASW);
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1011_xxxx: // mov: i->r
+ begin
+ seq_addr <= op[3] ? `MOVIRW : `MOVIRB;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b1;
+ imm_size <= op[3];
+
+ src <= 4'b0;
+ dst <= { 1'b0, op[2:0] };
+ end
+
+ 8'b1100_0010: // ret near with value
+ begin
+ seq_addr <= `RETNV;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b1;
+ imm_size <= 1'b1;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1100_0011: // ret near
+ begin
+ seq_addr <= `RETN0;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1100_0100: // les
+ begin
+ seq_addr <= `LES;
+ need_modrm <= 1'b1;
+ need_off <= need_off_mod;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ src <= { 1'b0, srcm };
+ dst <= 4'b0;
+ end
+
+ 8'b1100_0101: // lds
+ begin
+ seq_addr <= `LDS;
+ need_modrm <= 1'b1;
+ need_off <= need_off_mod;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ src <= { 1'b0, srcm };
+ dst <= 4'b0;
+ end
+
+ 8'b1100_011x: // mov: i->m (or i->r non-standard)
+ begin
+ seq_addr <= (mod==2'b11) ? (b ? `MOVIRB : `MOVIRW)
+ : (b ? `MOVIMB : `MOVIMW);
+ need_modrm <= 1'b1;
+ need_off <= need_off_mod;
+ need_imm <= 1'b1;
+ imm_size <= ~b;
+
+ src <= 4'b0;
+ dst <= { 1'b0, rm };
+ end
+
+ 8'b1100_1010: // ret far with value
+ begin
+ seq_addr <= `RETFV;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b1;
+ imm_size <= 1'b1;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1100_1011: // ret far
+ begin
+ seq_addr <= `RETF0;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1100_1100: // int 3
+ begin
+ seq_addr <= `INT3;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1100_1101: // int
+ begin
+ seq_addr <= `INT;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b1;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1100_1110: // into
+ begin
+ seq_addr <= `INTO;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1100_1111: // iret
+ begin
+ seq_addr <= `IRET;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1101_00xx: // sal/shl
+ begin
+ seq_addr <= (regm==3'b010) ? ((mod==2'b11) ?
+ (op[1] ? (op[0] ? `RCLCRW : `RCLCRB )
+ : (op[0] ? `RCL1RW : `RCL1RB ))
+ : (op[1] ? (op[0] ? `RCLCMW : `RCLCMB )
+ : (op[0] ? `RCL1MW : `RCL1MB )))
+ : ((regm==3'b011) ? ((mod==2'b11) ?
+ (op[1] ? (op[0] ? `RCRCRW : `RCRCRB )
+ : (op[0] ? `RCR1RW : `RCR1RB ))
+ : (op[1] ? (op[0] ? `RCRCMW : `RCRCMB )
+ : (op[0] ? `RCR1MW : `RCR1MB )))
+ : ((regm==3'b001) ? ((mod==2'b11) ?
+ (op[1] ? (op[0] ? `RORCRW : `RORCRB )
+ : (op[0] ? `ROR1RW : `ROR1RB ))
+ : (op[1] ? (op[0] ? `RORCMW : `RORCMB )
+ : (op[0] ? `ROR1MW : `ROR1MB )))
+ : ((regm==3'b000) ? ((mod==2'b11) ?
+ (op[1] ? (op[0] ? `ROLCRW : `ROLCRB )
+ : (op[0] ? `ROL1RW : `ROL1RB ))
+ : (op[1] ? (op[0] ? `ROLCMW : `ROLCMB )
+ : (op[0] ? `ROL1MW : `ROL1MB )))
+ : ( (regm==3'b100) ? ((mod==2'b11) ?
+ (op[1] ? (op[0] ? `SALCRW : `SALCRB )
+ : (op[0] ? `SAL1RW : `SAL1RB ))
+ : (op[1] ? (op[0] ? `SALCMW : `SALCMB )
+ : (op[0] ? `SAL1MW : `SAL1MB )))
+ : ( (regm==3'b111) ? ((mod==2'b11) ?
+ (op[1] ? (op[0] ? `SARCRW : `SARCRB )
+ : (op[0] ? `SAR1RW : `SAR1RB ))
+ : (op[1] ? (op[0] ? `SARCMW : `SARCMB )
+ : (op[0] ? `SAR1MW : `SAR1MB )))
+ : ((mod==2'b11) ?
+ (op[1] ? (op[0] ? `SHRCRW : `SHRCRB )
+ : (op[0] ? `SHR1RW : `SHR1RB ))
+ : (op[1] ? (op[0] ? `SHRCMW : `SHRCMB )
+ : (op[0] ? `SHR1MW : `SHR1MB ))))))));
+
+ need_modrm <= 1'b1;
+ need_off <= need_off_mod;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ 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;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1101_0101: // aad
+ begin
+ seq_addr <= `AAD;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b1;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1101_0111: // xlat
+ begin
+ seq_addr <= `XLAT;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1110_0000: // loopne
+ begin
+ seq_addr <= `LOOPNE;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b1;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1110_0001: // loope
+ begin
+ seq_addr <= `LOOPE;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b1;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1110_0010: // loop
+ begin
+ seq_addr <= `LOOP;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b1;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1110_0011: // jcxz
+ begin
+ seq_addr <= `JCXZ;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b1;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1110_010x: // in imm
+ begin
+ seq_addr <= b ? `INIB : `INIW;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b1;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1110_011x: // out imm
+ begin
+ seq_addr <= b ? `OUTIB : `OUTIW;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b1;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1110_1000: // call same segment
+ begin
+ seq_addr <= `CALLN;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b1;
+ imm_size <= 1'b1;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1110_10x1: // jmp direct
+ begin
+ seq_addr <= `JMPI;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b1;
+ imm_size <= ~op[1];
+
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1110_1010: // jmp indirect different segment
+ begin
+ seq_addr <= `LJMPI;
+ need_modrm <= 1'b0;
+ need_off <= 1'b1;
+ need_imm <= 1'b1;
+ imm_size <= 1'b1;
+
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1110_110x: // in dx
+ begin
+ seq_addr <= b ? `INRB : `INRW;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1110_111x: // out dx
+ begin
+ seq_addr <= b ? `OUTRB : `OUTRW;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1111_0100: // hlt
+ begin
+ seq_addr <= `HLT;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1111_0101: // cmc
+ begin
+ seq_addr <= `CMC;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1111_011x: // test, not, neg, mul, imul
+ begin
+ case (regm)
+ 3'b000: seq_addr <= (mod==2'b11) ?
+ (b ? `TSTIRB : `TSTIRW) : (b ? `TSTIMB : `TSTIMW);
+ 3'b010: seq_addr <= (mod==2'b11) ?
+ (b ? `NOTRB : `NOTRW) : (b ? `NOTMB : `NOTMW);
+ 3'b011: seq_addr <= (mod==2'b11) ?
+ (b ? `NEGRB : `NEGRW) : (b ? `NEGMB : `NEGMW);
+ 3'b100: seq_addr <= (mod==2'b11) ?
+ (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
+
+ need_modrm <= 1'b1;
+ need_off <= need_off_mod;
+ need_imm <= (regm == 3'b000); // imm on test
+ imm_size <= ~b;
+ dst <= { 1'b0, modrm[2:0] };
+ src <= { 1'b0, modrm[2:0] };
+ end
+
+ 8'b1111_1000: // clc
+ begin
+ seq_addr <= `CLC;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1111_1001: // stc
+ begin
+ seq_addr <= `STC;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1111_1010: // cli
+ begin
+ seq_addr <= `CLI;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1111_1011: // sti
+ begin
+ seq_addr <= `STI;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1111_1100: // cld
+ begin
+ seq_addr <= `CLD;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1111_1101: // std
+ begin
+ seq_addr <= `STD;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ 8'b1111_1110: // inc
+ begin
+ case (regm)
+ 3'b000: seq_addr <= (mod==2'b11) ? `INCRB : `INCMB;
+ 3'b001: seq_addr <= (mod==2'b11) ? `DECRB : `DECMB;
+ default: seq_addr <= `NOP;
+ endcase
+ need_modrm <= 1'b1;
+ need_off <= need_off_mod;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+
+ src <= { 1'b0, rm };
+ dst <= 4'b0;
+ end
+
+ 8'b1111_1111:
+ begin
+ case (regm)
+ 3'b000: seq_addr <= (mod==2'b11) ? `INCRW : `INCMW;
+ 3'b001: seq_addr <= (mod==2'b11) ? `DECRW : `DECMW;
+ 3'b010: seq_addr <= (mod==2'b11) ? `CALLNR : `CALLNM;
+ 3'b011: seq_addr <= `CALLFM;
+ 3'b100: seq_addr <= (mod==2'b11) ? `JMPR : `JMPM;
+ 3'b101: seq_addr <= `LJMPM;
+ 3'b110: seq_addr <= (mod==2'b11) ? `PUSHR : `PUSHM;
+ default: seq_addr <= `NOP;
+ endcase
+ need_modrm <= 1'b1;
+ need_off <= need_off_mod;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+
+ src <= { 1'b0, rm };
+ dst <= 4'b0;
+ end
+
+ default: // hlt
+ begin
+ seq_addr <= `HLT;
+ need_modrm <= 1'b0;
+ need_off <= 1'b0;
+ need_imm <= 1'b0;
+ imm_size <= 1'b0;
+
+ src <= 4'b0;
+ dst <= 4'b0;
+ end
+
+ endcase
+
+endmodule
+
+module memory_regs (
+ input [2:0] rm,
+ input [1:0] mod,
+ input [2:0] sovr_pr,
+
+ output reg [3:0] base,
+ output reg [3:0] index,
+ output [1:0] seg
+ );
+
+ // Register declaration
+ reg [1:0] s;
+
+ // Continuous assignments
+ assign seg = sovr_pr[2] ? sovr_pr[1:0] : s;
+
+ // Behaviour
+ always @(rm or mod)
+ case (rm)
+ 3'b000: begin base <= 4'b0011; index <= 4'b0110; s <= 2'b11; end
+ 3'b001: begin base <= 4'b0011; index <= 4'b0111; s <= 2'b11; end
+ 3'b010: begin base <= 4'b0101; index <= 4'b0110; s <= 2'b10; end
+ 3'b011: begin base <= 4'b0101; index <= 4'b0111; s <= 2'b10; end
+ 3'b100: begin base <= 4'b1100; index <= 4'b0110; s <= 2'b11; end
+ 3'b101: begin base <= 4'b1100; index <= 4'b0111; s <= 2'b11; end
+ 3'b110: begin base <= mod ? 4'b0101 : 4'b1100; index <= 4'b1100;
+ s <= mod ? 2'b10 : 2'b11; end
+ 3'b111: begin base <= 4'b0011; index <= 4'b1100; s <= 2'b11; end
+ endcase
+endmodule
+
+module micro_data (
+ input [`MICRO_ADDR_WIDTH-1:0] n_micro,
+ input [15:0] off_i,
+ input [15:0] imm_i,
+ input [3:0] src,
+ input [3:0] dst,
+ input [3:0] base,
+ input [3:0] index,
+ input [1:0] seg,
+ output [`IR_SIZE-1:0] ir,
+ output [15:0] off_o,
+ output [15:0] imm_o
+ );
+
+ // Net declarations
+ wire [`MICRO_DATA_WIDTH-1:0] micro_o;
+ wire [17:0] high_ir;
+ wire var_s, var_off;
+ wire [1:0] var_a, var_b, var_c, var_d;
+ wire [2:0] var_imm;
+
+ wire [3:0] addr_a, addr_b, addr_c, addr_d;
+ wire [3:0] micro_a, micro_b, micro_c, micro_d;
+ wire [1:0] addr_s, micro_s;
+
+ // Module instantiations
+ micro_rom m0 (n_micro, micro_o);
+
+ // Assignments
+ assign micro_s = micro_o[1:0];
+ assign micro_a = micro_o[5:2];
+ assign micro_b = micro_o[9:6];
+ assign micro_c = micro_o[13:10];
+ assign micro_d = micro_o[17:14];
+ assign high_ir = micro_o[35:18];
+ assign var_s = micro_o[36];
+ assign var_a = micro_o[38:37];
+ assign var_b = micro_o[40:39];
+ assign var_c = micro_o[42:41];
+ assign var_d = micro_o[44:43];
+ assign var_off = micro_o[45];
+ assign var_imm = micro_o[48:46];
+
+ assign imm_o = var_imm == 3'd0 ? (16'h0000)
+ : (var_imm == 3'd1 ? (16'h0002)
+ : (var_imm == 3'd2 ? (16'h0004)
+ : (var_imm == 3'd3 ? off_i
+ : (var_imm == 3'd4 ? imm_i
+ : (var_imm == 3'd5 ? 16'hffff
+ : (var_imm == 3'd6 ? 16'b11 : 16'd1))))));
+
+ assign off_o = var_off ? off_i : 16'h0000;
+
+ assign addr_a = var_a == 2'd0 ? micro_a
+ : (var_a == 2'd1 ? base
+ : (var_a == 2'd2 ? dst : src ));
+ assign addr_b = var_b == 2'd0 ? micro_b
+ : (var_b == 2'd1 ? index : src);
+ assign addr_c = var_c == 2'd0 ? micro_c
+ : (var_c == 2'd1 ? dst : src);
+ assign addr_d = var_d == 2'd0 ? micro_d
+ : (var_d == 2'd1 ? dst : src);
+ assign addr_s = var_s ? seg : micro_s;
+
+ assign ir = { high_ir, addr_d, addr_c, addr_b, addr_a, addr_s };
+endmodule
+
+module micro_rom (
+ input [`MICRO_ADDR_WIDTH-1:0] addr,
+ output [`MICRO_DATA_WIDTH-1:0] q
+ );
+
+ // Registers, nets and parameters
+ reg [`MICRO_DATA_WIDTH-1:0] rom[0:2**`MICRO_ADDR_WIDTH-1];
+
+ // Assignments
+ assign q = rom[addr];
+
+ // Behaviour
+ initial $readmemb("/home/zeus/zet/rtl-model/micro_rom.dat", rom);
+endmodule
+
+module seq_rom (
+ input [`SEQ_ADDR_WIDTH-1:0] addr,
+ output [`SEQ_DATA_WIDTH-1:0] q
+ );
+
+ // Registers, nets and parameters
+ reg [`SEQ_DATA_WIDTH-1:0] rom[0:2**`SEQ_ADDR_WIDTH-1];
+
+ // Assignments
+ assign q = rom[addr];
+
+ // Behaviour
+ initial $readmemb("/home/zeus/zet/rtl-model/seq_rom.dat", rom);
+endmodule
trunk/cores/zet/rtl/fetch.v
Property changes :
Added: svn:mergeinfo
## -0,0 +0,0 ##
Index: trunk/cores/zet/rtl/jmp_cond.v
===================================================================
--- trunk/cores/zet/rtl/jmp_cond.v (nonexistent)
+++ trunk/cores/zet/rtl/jmp_cond.v (revision 55)
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2008 Zeus Gomez Marmolejo
+ *
+ * This file is part of the Zet processor. This processor is free
+ * hardware; you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by the Free Software
+ * Foundation; either version 3, or (at your option) any later version.
+ *
+ * Zet is distrubuted 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 Zet; see the file COPYING. If not, see
+ * .
+ */
+
+`timescale 1ns/10ps
+
+module jmp_cond (
+ input [4:0] logic_flags,
+ input [3:0] cond,
+ input is_cx,
+ input [15:0] cx,
+ output reg jmp
+ );
+
+ // Net declarations
+ wire of, sf, zf, pf, cf;
+ wire cx_zero;
+
+ // Assignments
+ assign of = logic_flags[4];
+ assign sf = logic_flags[3];
+ assign zf = logic_flags[2];
+ assign pf = logic_flags[1];
+ assign cf = logic_flags[0];
+ assign cx_zero = ~(|cx);
+
+ // Behaviour
+ always @(cond or is_cx or cx_zero or zf or of or cf or sf or pf)
+ if (is_cx) case (cond)
+ 4'b0000: jmp <= cx_zero; /* jcxz */
+ 4'b0001: jmp <= ~cx_zero; /* loop */
+ 4'b0010: jmp <= zf & ~cx_zero; /* loopz */
+ default: jmp <= ~zf & ~cx_zero; /* loopnz */
+ endcase
+ else case (cond)
+ 4'b0000: jmp <= of;
+ 4'b0001: jmp <= ~of;
+ 4'b0010: jmp <= cf;
+ 4'b0011: jmp <= ~cf;
+ 4'b0100: jmp <= zf;
+ 4'b0101: jmp <= ~zf;
+ 4'b0110: jmp <= cf | zf;
+ 4'b0111: jmp <= ~cf & ~zf;
+
+ 4'b1000: jmp <= sf;
+ 4'b1001: jmp <= ~sf;
+ 4'b1010: jmp <= pf;
+ 4'b1011: jmp <= ~pf;
+ 4'b1100: jmp <= (sf ^ of);
+ 4'b1101: jmp <= (sf ^~ of);
+ 4'b1110: jmp <= zf | (sf ^ of);
+ 4'b1111: jmp <= ~zf & (sf ^~ of);
+ endcase
+endmodule
trunk/cores/zet/rtl/jmp_cond.v
Property changes :
Added: svn:mergeinfo
## -0,0 +0,0 ##
Index: trunk/cores/zet/rtl/util/div_uu.v
===================================================================
--- trunk/cores/zet/rtl/util/div_uu.v (nonexistent)
+++ trunk/cores/zet/rtl/util/div_uu.v (revision 55)
@@ -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.3 2003/09/17 13:08:53 rherveille Exp $
+//
+// $Date: 2003/09/17 13:08:53 $
+// $Revision: 1.3 $
+// $Author: rherveille $
+// $Locker: $
+// $State: Exp $
+//
+// Change History:
+// $Log: div_uu.v,v $
+// 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] <= 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] <= gen_s(s_pipe[n1-1], d_pipe[n1-1]);
+
+ // generate quotient pipe
+ always @(posedge clk)
+ q_pipe[0] <= 0;
+
+ always @(posedge clk)
+ if(ena)
+ for(n2=1; n2 < d_width; n2=n2+1)
+ q_pipe[n2] <= 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] <= ovf_pipe[n3-1];
+ div0_pipe[n3] <= div0_pipe[n3-1];
+ end
+
+ // assign outputs
+ always @(posedge clk)
+ if(ena)
+ ovf <= ovf_pipe[d_width];
+
+ always @(posedge clk)
+ if(ena)
+ div0 <= div0_pipe[d_width];
+
+ always @(posedge clk)
+ if(ena)
+ q <= gen_q(q_pipe[d_width-1], s_pipe[d_width]);
+
+ always @(posedge clk)
+ if(ena)
+ s <= assign_s(s_pipe[d_width], d_pipe[d_width]);
+endmodule
+
+
+
Index: trunk/cores/zet/rtl/util/div_su.v
===================================================================
--- trunk/cores/zet/rtl/util/div_su.v (nonexistent)
+++ trunk/cores/zet/rtl/util/div_su.v (revision 55)
@@ -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.2 2002/10/31 13:54:58 rherveille Exp $
+//
+// $Date: 2002/10/31 13:54:58 $
+// $Revision: 1.2 $
+// $Author: rherveille $
+// $Locker: $
+// $State: Exp $
+//
+// Change History:
+// $Log: div_su.v,v $
+// 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 <= ~d +1'h1;
+ else
+ id <= d;
+
+ // check z, take abs value
+ always @(posedge clk)
+ if (ena)
+ if (z[z_width-1])
+ iz <= ~z +1'h1;
+ else
+ iz <= z;
+
+ // generate szpipe (z sign bit pipe)
+ integer n;
+ always @(posedge clk)
+ if(ena)
+ begin
+ szpipe[0] <= z[z_width-1];
+
+ for(n=1; n <= d_width+1; n=n+1)
+ szpipe[n] <= szpipe[n-1];
+ end
+
+ // generate sdpipe (d sign bit pipe)
+ integer m;
+ always @(posedge clk)
+ if(ena)
+ begin
+ sdpipe[0] <= d[d_width-1];
+
+ for(m=1; m <= d_width+1; m=m+1)
+ sdpipe[m] <= 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 <= (szpipe[d_width+1]^sdpipe[d_width+1]) ?
+ ((~iq) + 1'h1) : ({1'b0, iq});
+ s <= (szpipe[d_width+1]) ?
+ ((~is) + 1'h1) : ({1'b0, is});
+ end
+
+ // delay flags same as results
+ always @(posedge clk)
+ if(ena)
+ begin
+ div0 <= idiv0;
+ ovf <= iovf;
+ end
+endmodule
Index: trunk/cores/zet/rtl/util/primitives.v
===================================================================
--- trunk/cores/zet/rtl/util/primitives.v (nonexistent)
+++ trunk/cores/zet/rtl/util/primitives.v (revision 55)
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 2008 Zeus Gomez Marmolejo
+ *
+ * This file is part of the Zet processor. This processor is free
+ * hardware; you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by the Free Software
+ * Foundation; either version 3, or (at your option) any later version.
+ *
+ * Zet is distrubuted 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 Zet; see the file COPYING. If not, see
+ * .
+ */
+
+//
+// Multiplexor 8:1 de 16 bits d'amplada
+//
+module mux8_16(sel, in0, in1, in2, in3, in4, in5, in6, in7, out);
+ input [2:0] sel;
+ input [15:0] in0, in1, in2, in3, in4, in5, in6, in7;
+ output [15:0] out;
+
+ reg [15:0] out;
+
+ always @(sel or in0 or in1 or in2 or in3 or in4 or in5 or in6 or in7)
+ case(sel)
+ 3'd0: out = in0;
+ 3'd1: out = in1;
+ 3'd2: out = in2;
+ 3'd3: out = in3;
+ 3'd4: out = in4;
+ 3'd5: out = in5;
+ 3'd6: out = in6;
+ 3'd7: out = in7;
+ endcase
+endmodule
+
+
+//
+// Multiplexor 8:1 de 8 bits d'amplada
+//
+/*
+module mux8_8(sel, in0, in1, in2, in3, in4, in5, in6, in7, out);
+ input [2:0] sel;
+ input [7:0] in0, in1, in2, in3, in4, in5, in6, in7;
+ output [7:0] out;
+
+ reg [7:0] out;
+
+ always @(sel or in0 or in1 or in2 or in3 or in4 or in5 or in6 or in7)
+ case(sel)
+ 3'd0: out = in0;
+ 3'd1: out = in1;
+ 3'd2: out = in2;
+ 3'd3: out = in3;
+ 3'd4: out = in4;
+ 3'd5: out = in5;
+ 3'd6: out = in6;
+ 3'd7: out = in7;
+ endcase
+endmodule
+*/
+//
+// Multiplexor 8:1 d'1 bit d'amplada
+//
+module mux8_1(sel, in0, in1, in2, in3, in4, in5, in6, in7, out);
+ input [2:0] sel;
+ input in0, in1, in2, in3, in4, in5, in6, in7;
+ output out;
+
+ reg out;
+
+ always @(sel or in0 or in1 or in2 or in3 or in4 or in5 or in6 or in7)
+ case(sel)
+ 3'd0: out = in0;
+ 3'd1: out = in1;
+ 3'd2: out = in2;
+ 3'd3: out = in3;
+ 3'd4: out = in4;
+ 3'd5: out = in5;
+ 3'd6: out = in6;
+ 3'd7: out = in7;
+ endcase
+endmodule
+
+//
+// Multiplexor 4:1 de 16 bits d'amplada
+//
+module mux4_16(sel, in0, in1, in2, in3, out);
+ input [1:0] sel;
+ input [15:0] in0, in1, in2, in3;
+ output [15:0] out;
+
+ reg [15:0] out;
+
+ always @(sel or in0 or in1 or in2 or in3)
+ case(sel)
+ 2'd0: out = in0;
+ 2'd1: out = in1;
+ 2'd2: out = in2;
+ 2'd3: out = in3;
+ endcase
+endmodule
+
+/*
+//
+// Multiplexor 4:1 de 1 bits d'amplada
+//
+module mux4_1(sel, in0, in1, in2, in3, out);
+ input [1:0] sel;
+ input in0, in1, in2, in3;
+ output out;
+
+ reg out;
+
+ always @(sel or in0 or in1 or in2 or in3)
+ case(sel)
+ 2'd0: out = in0;
+ 2'd1: out = in1;
+ 2'd2: out = in2;
+ 2'd3: out = in3;
+ endcase
+endmodule
+
+//
+// Multiplexor 2:1 de 8 bits d'amplada
+//
+module mux2_8(sel, in0, in1, out);
+ input sel;
+ input [7:0] in0, in1;
+ output [7:0] out;
+
+ reg [7:0] out;
+
+ always @(sel or in0 or in1)
+ case(sel)
+ 1'd0: out = in0;
+ 1'd1: out = in1;
+ endcase
+endmodule
+
+//
+// Multiplexor 4:1 de 32 bits d'amplada
+//
+
+module mux4_32(sel, in0, in1, in2, in3, out);
+ input [1:0] sel;
+ input [31:0] in0, in1, in2, in3;
+ output [31:0] out;
+
+ reg [31:0] out;
+
+ always @(sel or in0 or in1 or in2 or in3)
+ case(sel)
+ 2'd0: out = in0;
+ 2'd1: out = in1;
+ 2'd2: out = in2;
+ 2'd3: out = in3;
+ endcase
+endmodule
+
+//
+// Multiplexor 8:1 de 17 bits d'amplada
+//
+module mux8_17(sel, in0, in1, in2, in3, in4, in5, in6, in7, out);
+ input [2:0] sel;
+ input [16:0] in0, in1, in2, in3, in4, in5, in6, in7;
+ output [16:0] out;
+
+ reg [16:0] out;
+
+ always @(sel or in0 or in1 or in2 or in3 or in4 or in5 or in6 or in7)
+ case(sel)
+ 3'd0: out = in0;
+ 3'd1: out = in1;
+ 3'd2: out = in2;
+ 3'd3: out = in3;
+ 3'd4: out = in4;
+ 3'd5: out = in5;
+ 3'd6: out = in6;
+ 3'd7: out = in7;
+ endcase
+endmodule
+*/
+
+/*
+//
+// 1 bit cell divider by 10
+//
+module div10b1 (
+ input [3:0] c,
+ input a,
+ output q,
+ output [3:0] r
+ );
+
+ // Continuous assignments
+ assign r = { c[3]&c[0] | c[2]&~c[1]&~c[0],
+ ~c[2]&c[1] | c[1]&c[0] | c[3]&~c[0],
+ c[3]&~c[0] | c[2]&c[1]&~c[0] | ~c[3]&~c[2]&~c[0],
+ a };
+ assign q = c[3] | c[2]&c[1] | c[2]&c[0];
+endmodule
+
+//
+// 8 bit divider by 10
+//
+module div10b8 (
+ input [7:0] a,
+ output [4:0] q,
+ output [3:0] r
+ );
+
+ // Net declarations
+ wire [3:0] c10, c21, c32, c43;
+
+ // Module instantiations
+ div10b1 bit4 (
+ .c ({1'b0, a[7:5]}),
+ .a (a[4]),
+ .q (q[4]),
+ .r (c43)
+ );
+
+ div10b1 bit3 (
+ .c (c43),
+ .a (a[3]),
+ .q (q[3]),
+ .r (c32)
+ );
+
+ div10b1 bit2 (
+ .c (c32),
+ .a (a[2]),
+ .q (q[2]),
+ .r (c21)
+ );
+
+ div10b1 bit1 (
+ .c (c21),
+ .a (a[1]),
+ .q (q[1]),
+ .r (c10)
+ );
+
+ div10b1 bit0 (
+ .c (c10),
+ .a (a[0]),
+ .q (q[0]),
+ .r (r)
+ );
+*/
+
+module fulladd16 (
+ input [15:0] x,
+ input [15:0] y,
+ input ci,
+ output co,
+ output [15:0] z,
+ input s
+ );
+
+ // Continuous assignments
+ assign {co,z} = {1'b0, x} + {s, y} + ci;
+endmodule
Index: trunk/cores/zet/rtl/util
===================================================================
--- trunk/cores/zet/rtl/util (nonexistent)
+++ trunk/cores/zet/rtl/util (revision 55)
trunk/cores/zet/rtl/util
Property changes :
Added: svn:mergeinfo
## -0,0 +0,0 ##
Index: trunk/cores/zet
===================================================================
--- trunk/cores/zet (nonexistent)
+++ trunk/cores/zet (revision 55)
trunk/cores/zet
Property changes :
Added: svn:mergeinfo
## -0,0 +0,0 ##