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

Subversion Repositories zet86

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /zet86/trunk
    from Rev 55 to Rev 54
    Reverse comparison

Rev 55 → Rev 54

cores/zet/rtl/jmp_cond.v Property changes : Deleted: svn:mergeinfo ## -0,0 +0,0 ## Index: cores/zet/rtl/util/div_su.v =================================================================== --- cores/zet/rtl/util/div_su.v (revision 55) +++ cores/zet/rtl/util/div_su.v (nonexistent) @@ -1,167 +0,0 @@ -///////////////////////////////////////////////////////////////////// -//// //// -//// 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: cores/zet/rtl/util/div_uu.v =================================================================== --- cores/zet/rtl/util/div_uu.v (revision 55) +++ cores/zet/rtl/util/div_uu.v (nonexistent) @@ -1,207 +0,0 @@ -///////////////////////////////////////////////////////////////////// -//// //// -//// 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: cores/zet/rtl/util/primitives.v =================================================================== --- cores/zet/rtl/util/primitives.v (revision 55) +++ cores/zet/rtl/util/primitives.v (nonexistent) @@ -1,269 +0,0 @@ -/* - * 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: cores/zet/rtl/util =================================================================== --- cores/zet/rtl/util (revision 55) +++ cores/zet/rtl/util (nonexistent)
cores/zet/rtl/util Property changes : Deleted: svn:mergeinfo ## -0,0 +0,0 ## Index: cores/zet/rtl/fetch.v =================================================================== --- cores/zet/rtl/fetch.v (revision 55) +++ cores/zet/rtl/fetch.v (nonexistent) @@ -1,1736 +0,0 @@ -/* - * 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
cores/zet/rtl/fetch.v Property changes : Deleted: svn:mergeinfo ## -0,0 +0,0 ## Index: cores/zet/rtl/defines.v =================================================================== --- cores/zet/rtl/defines.v (revision 55) +++ cores/zet/rtl/defines.v (nonexistent) @@ -1,27 +0,0 @@ -/* - * 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 - * . - */ - -`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
cores/zet/rtl/defines.v Property changes : Deleted: svn:mergeinfo ## -0,0 +0,0 ## Index: cores/zet/rtl/regfile.v =================================================================== --- cores/zet/rtl/regfile.v (revision 55) +++ cores/zet/rtl/regfile.v (nonexistent) @@ -1,113 +0,0 @@ -/* - * 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
cores/zet/rtl/regfile.v Property changes : Deleted: svn:mergeinfo ## -0,0 +0,0 ## Index: cores/zet/rtl/rotate.v =================================================================== --- cores/zet/rtl/rotate.v (revision 55) +++ cores/zet/rtl/rotate.v (nonexistent) @@ -1,140 +0,0 @@ -/* - * 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
cores/zet/rtl/rotate.v Property changes : Deleted: svn:mergeinfo ## -0,0 +0,0 ## Index: cores/zet/rtl/alu.v =================================================================== --- cores/zet/rtl/alu.v (revision 55) +++ cores/zet/rtl/alu.v (nonexistent) @@ -1,406 +0,0 @@ -/* - * 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
cores/zet/rtl/alu.v Property changes : Deleted: svn:mergeinfo ## -0,0 +0,0 ## Index: cores/zet/rtl/exec.v =================================================================== --- cores/zet/rtl/exec.v (revision 55) +++ cores/zet/rtl/exec.v (nonexistent) @@ -1,148 +0,0 @@ -/* - * 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
cores/zet/rtl/exec.v Property changes : Deleted: svn:mergeinfo ## -0,0 +0,0 ## Index: cores/zet/rtl/cpu.v =================================================================== --- cores/zet/rtl/cpu.v (revision 55) +++ cores/zet/rtl/cpu.v (nonexistent) @@ -1,312 +0,0 @@ -/* - * 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
cores/zet/rtl/cpu.v Property changes : Deleted: svn:mergeinfo ## -0,0 +0,0 ## Index: cores/zet =================================================================== --- cores/zet (revision 55) +++ cores/zet (nonexistent)
cores/zet Property changes : Deleted: svn:mergeinfo ## -0,0 +0,0 ## Index: rtl-model/cpu.v =================================================================== --- rtl-model/cpu.v (nonexistent) +++ rtl-model/cpu.v (revision 54) @@ -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 Index: rtl-model/fetch.v =================================================================== --- rtl-model/fetch.v (nonexistent) +++ rtl-model/fetch.v (revision 54) @@ -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 Index: rtl-model/util/div_uu.v =================================================================== --- rtl-model/util/div_uu.v (nonexistent) +++ rtl-model/util/div_uu.v (revision 54) @@ -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: rtl-model/util/div_su.v =================================================================== --- rtl-model/util/div_su.v (nonexistent) +++ rtl-model/util/div_su.v (revision 54) @@ -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: rtl-model/util/primitives.v =================================================================== --- rtl-model/util/primitives.v (nonexistent) +++ rtl-model/util/primitives.v (revision 54) @@ -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: rtl-model/defines.v =================================================================== --- rtl-model/defines.v (nonexistent) +++ rtl-model/defines.v (revision 54) @@ -0,0 +1,27 @@ +/* + * 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 + * . + */ + +`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 Index: rtl-model/regfile.v =================================================================== --- rtl-model/regfile.v (nonexistent) +++ rtl-model/regfile.v (revision 54) @@ -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 Index: rtl-model/exec.v =================================================================== --- rtl-model/exec.v (nonexistent) +++ rtl-model/exec.v (revision 54) @@ -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 Index: rtl-model/alu.v =================================================================== --- rtl-model/alu.v (nonexistent) +++ rtl-model/alu.v (revision 54) @@ -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 Index: rtl-model/rotate.v =================================================================== --- rtl-model/rotate.v (nonexistent) +++ rtl-model/rotate.v (revision 54) @@ -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 Index: rtl-model/jmp_cond.v =================================================================== --- rtl-model/jmp_cond.v (nonexistent) +++ rtl-model/jmp_cond.v (revision 54) @@ -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

powered by: WebSVN 2.1.0

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