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

Subversion Repositories eco32

[/] [eco32/] [trunk/] [fpga/] [experiments/] [memctrl/] [sim/] [memctrl-0/] [ramctrl/] [ramctrl.v] - Rev 312

Compare with Previous | Blame | View Log

//
// ramctrl.v -- RAM controller
//
 
 
`include "ramctrl/ram.v"
 
 
`timescale 1ns/10ps
`default_nettype none
 
 
module ramctrl(clk, rst,
               inst_stb, inst_addr,
               inst_dout, inst_ack,
               inst_timeout,
               data_stb, data_we,
               data_addr, data_din,
               data_dout, data_ack,
               data_timeout);
    input clk;
    input rst;
    input inst_stb;
    input [25:0] inst_addr;
    output [63:0] inst_dout;
    output reg inst_ack;
    output reg inst_timeout;
    input data_stb;
    input data_we;
    input [25:0] data_addr;
    input [63:0] data_din;
    output [63:0] data_dout;
    output reg data_ack;
    output reg data_timeout;
 
  reg ram_stb;
  reg ram_we;
  wire [22:0] ram_addr;
  wire [31:0] ram_dout;
  wire [31:0] ram_din;
  wire ram_ack;
 
  wire inst_addr_out_of_range;
  wire data_addr_out_of_range;
 
  reg ram_as;
  reg ram_a0;
 
  reg ram_ds;
 
  reg [63:0] data;
  reg data_wh;
  reg data_wl;
 
  reg [3:0] state;
  reg [3:0] next_state;
 
  //
  // create ram instance
  //
 
  ram ram_1(
    .clk(clk),
    .rst(rst),
    .stb(ram_stb),
    .we(ram_we),
    .addr(ram_addr[22:0]),
    .data_in(ram_dout[31:0]),
    .data_out(ram_din[31:0]),
    .ack(ram_ack)
  );
 
  //
  // address range check
  //
 
  assign inst_addr_out_of_range = | inst_addr[25:22];
  assign data_addr_out_of_range = | data_addr[25:22];
 
  //
  // address output to ram
  //
 
  assign ram_addr[22:0] =
    ~ram_as ? { inst_addr[21:0], ram_a0 } :
              { data_addr[21:0], ram_a0 };
 
  //
  // data output to ram
  //
 
  assign ram_dout[31:0] =
    ~ram_ds ? data_din[63:32] : data_din[31:0];
 
  //
  // data output to cache
  //
 
  always @(posedge clk) begin
    if (data_wh) begin
      data[63:32] <= ram_din[31:0];
    end
    if (data_wl) begin
      data[31: 0] <= ram_din[31:0];
    end
  end
 
  assign inst_dout[63:0] = data[63:0];
  assign data_dout[63:0] = data[63:0];
 
  //
  // ramctrl state machine
  //
 
  always @(posedge clk) begin
    if (rst) begin
      state <= 0;
    end else begin
      state <= next_state;
    end
  end
 
  always @(*) begin
    case (state)
      4'd0:
        // idle, request arbitration
        begin
          inst_ack = 1'b0;
          inst_timeout = 1'b0;
          data_ack = 1'b0;
          data_timeout = 1'b0;
          ram_stb = 1'b0;
          ram_we = 1'b0;
          ram_as = 1'bx;
          ram_a0 = 1'bx;
          ram_ds = 1'bx;
          data_wh = 1'b0;
          data_wl = 1'b0;
          if (data_stb) begin
            if (data_addr_out_of_range) begin
              // illegal data address
              next_state = 4'd11;
            end else begin
              // data address is ok
              if (data_we) begin
                // data write request
                next_state = 4'd7;
              end else begin
                // data read request
                next_state = 4'd4;
              end
            end
          end else begin
            if (inst_stb) begin
              if (inst_addr_out_of_range) begin
                // illegal inst address
                next_state = 4'd10;
              end else begin
                // inst address is ok
                // inst read request
                next_state = 4'd1;
              end
            end else begin
              // no request
              next_state = 4'd0;
            end
          end
        end
      4'd1:
        // inst read, phase 1
        begin
          inst_ack = 1'b0;
          inst_timeout = 1'b0;
          data_ack = 1'b0;
          data_timeout = 1'b0;
          ram_stb = 1'b1;
          ram_we = 1'b0;
          ram_as = 1'b0;
          ram_a0 = 1'b0;
          ram_ds = 1'bx;
          data_wh = ram_ack;
          data_wl = 1'b0;
          if (ram_ack) begin
            next_state = 4'd2;
          end else begin
            next_state = 4'd1;
          end
        end
      4'd2:
        // inst read, phase 2
        begin
          inst_ack = 1'b0;
          inst_timeout = 1'b0;
          data_ack = 1'b0;
          data_timeout = 1'b0;
          ram_stb = 1'b1;
          ram_we = 1'b0;
          ram_as = 1'b0;
          ram_a0 = 1'b1;
          ram_ds = 1'bx;
          data_wh = 1'b0;
          data_wl = ram_ack;
          if (ram_ack) begin
            next_state = 4'd3;
          end else begin
            next_state = 4'd2;
          end
        end
      4'd3:
        // inst read, phase 3
        begin
          inst_ack = 1'b1;
          inst_timeout = 1'b0;
          data_ack = 1'b0;
          data_timeout = 1'b0;
          ram_stb = 1'b0;
          ram_we = 1'b0;
          ram_as = 1'bx;
          ram_a0 = 1'bx;
          ram_ds = 1'bx;
          data_wh = 1'b0;
          data_wl = 1'b0;
          next_state = 4'd0;
        end
      4'd4:
        // data read, phase 1
        begin
          inst_ack = 1'b0;
          inst_timeout = 1'b0;
          data_ack = 1'b0;
          data_timeout = 1'b0;
          ram_stb = 1'b1;
          ram_we = 1'b0;
          ram_as = 1'b1;
          ram_a0 = 1'b0;
          ram_ds = 1'bx;
          data_wh = ram_ack;
          data_wl = 1'b0;
          if (ram_ack) begin
            next_state = 4'd5;
          end else begin
            next_state = 4'd4;
          end
        end
      4'd5:
        // data read, phase 2
        begin
          inst_ack = 1'b0;
          inst_timeout = 1'b0;
          data_ack = 1'b0;
          data_timeout = 1'b0;
          ram_stb = 1'b1;
          ram_we = 1'b0;
          ram_as = 1'b1;
          ram_a0 = 1'b1;
          ram_ds = 1'bx;
          data_wh = 1'b0;
          data_wl = ram_ack;
          if (ram_ack) begin
            next_state = 4'd6;
          end else begin
            next_state = 4'd5;
          end
        end
      4'd6:
        // data read, phase 3
        begin
          inst_ack = 1'b0;
          inst_timeout = 1'b0;
          data_ack = 1'b1;
          data_timeout = 1'b0;
          ram_stb = 1'b0;
          ram_we = 1'b0;
          ram_as = 1'bx;
          ram_a0 = 1'bx;
          ram_ds = 1'bx;
          data_wh = 1'b0;
          data_wl = 1'b0;
          next_state = 4'd0;
        end
      4'd7:
        // data write, phase 1
        begin
          inst_ack = 1'b0;
          inst_timeout = 1'b0;
          data_ack = 1'b0;
          data_timeout = 1'b0;
          ram_stb = 1'b1;
          ram_we = 1'b1;
          ram_as = 1'b1;
          ram_a0 = 1'b0;
          ram_ds = 1'b0;
          data_wh = 1'b0;
          data_wl = 1'b0;
          if (ram_ack) begin
            next_state = 4'd8;
          end else begin
            next_state = 4'd7;
          end
        end
      4'd8:
        // data write, phase 2
        begin
          inst_ack = 1'b0;
          inst_timeout = 1'b0;
          data_ack = 1'b0;
          data_timeout = 1'b0;
          ram_stb = 1'b1;
          ram_we = 1'b1;
          ram_as = 1'b1;
          ram_a0 = 1'b1;
          ram_ds = 1'b1;
          data_wh = 1'b0;
          data_wl = 1'b0;
          if (ram_ack) begin
            next_state = 4'd9;
          end else begin
            next_state = 4'd8;
          end
        end
      4'd9:
        // data write, phase 3
        begin
          inst_ack = 1'b0;
          inst_timeout = 1'b0;
          data_ack = 1'b1;
          data_timeout = 1'b0;
          ram_stb = 1'b0;
          ram_we = 1'b0;
          ram_as = 1'bx;
          ram_a0 = 1'bx;
          ram_ds = 1'bx;
          data_wh = 1'b0;
          data_wl = 1'b0;
          next_state = 4'd0;
        end
      4'd10:
        // illegal inst address
        begin
          inst_ack = 1'b0;
          inst_timeout = 1'b1;
          data_ack = 1'b0;
          data_timeout = 1'b0;
          ram_stb = 1'b0;
          ram_we = 1'b0;
          ram_as = 1'bx;
          ram_a0 = 1'bx;
          ram_ds = 1'bx;
          data_wh = 1'b0;
          data_wl = 1'b0;
          next_state = 4'd0;
        end
      4'd11:
        // illegal data address
        begin
          inst_ack = 1'b0;
          inst_timeout = 1'b0;
          data_ack = 1'b0;
          data_timeout = 1'b1;
          ram_stb = 1'b0;
          ram_we = 1'b0;
          ram_as = 1'bx;
          ram_a0 = 1'bx;
          ram_ds = 1'bx;
          data_wh = 1'b0;
          data_wl = 1'b0;
          next_state = 4'd0;
        end
      default:
        // not used
        begin
          inst_ack = 1'b0;
          inst_timeout = 1'b0;
          data_ack = 1'b0;
          data_timeout = 1'b0;
          ram_stb = 1'b0;
          ram_we = 1'b0;
          ram_as = 1'bx;
          ram_a0 = 1'bx;
          ram_ds = 1'bx;
          data_wh = 1'b0;
          data_wl = 1'b0;
          next_state = 4'd0;
        end
    endcase
  end
 
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.