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

Subversion Repositories zet86

[/] [zet86/] [trunk/] [cores/] [zet/] [rtl/] [cpu.v] - Diff between revs 53 and 55

Show entire file | Details | Blame | View Log

Rev 53 Rev 55
Line 1... Line 1...
 
/*
 
 *  Copyright (c) 2008  Zeus Gomez Marmolejo <zeus@opencores.org>
 
 *
 
 *  This file is part of the Zet processor. This processor is free
 
 *  hardware; you can redistribute it and/or modify it under the terms of
 
 *  the GNU General Public License as published by the Free Software
 
 *  Foundation; either version 3, or (at your option) any later version.
 
 *
 
 *  Zet is distrubuted in the hope that it will be useful, but WITHOUT
 
 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 
 *  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
 
 *  License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with Zet; see the file COPYING. If not, see
 
 *  <http://www.gnu.org/licenses/>.
 
 */
 
 
 
`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
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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