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

Subversion Repositories zet86

[/] [zet86/] [trunk/] [cores/] [zet/] [rtl/] [cpu.v] - Rev 55

Compare with Previous | Blame | View Log

/*
 *  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
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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