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

Subversion Repositories wb_verilog

[/] [wb_verilog/] [trunk/] [wb_master.v] - Diff between revs 4 and 6

Show entire file | Details | Blame | View Log

Rev 4 Rev 6
Line 1... Line 1...
 
//                              -*- Mode: Verilog -*-
 
// Filename        : wb_master.v
 
// Description     : Wishbone Master Behavorial
 
// Author          : Winefred Washington
 
// Created On      : Thu Jan 11 21:18:41 2001
 
// Last Modified By: .
 
// Last Modified On: .
 
// Update Count    : 0
 
// Status          : Unknown, Use with caution!
 
 
 
//        Description                   Specification
 
// General Description:            8, 16, 32-bit WISHBONE Master
 
// Supported cycles:               MASTER, READ/WRITE
 
//                                 MASTER, BLOCK READ/WRITE
 
//                                 MASTER, RMW
 
// Data port, size:                8, 16, 32-bit
 
// Data port, granularity          8-bit
 
// Data port, Max. operand size    32-bit
 
// Data transfer ordering:         little endian
 
// Data transfer sequencing:       undefined
 
//
 
 
 
module WB_MASTER32(CLK_I, RST_I, TAG_I, TAG_O,
 
                   ACK_I, ADR_O, CYC_O, DAT_I, DAT_O, ERR_I, RTY_I, SEL_O, STB_O, WE_O);
 
 
 
   input                CLK_I;
 
   input                RST_I;
 
   input [3:0]           TAG_I;
 
   output [3:0]  TAG_O;
 
   input                ACK_I;
 
   output [31:0]         ADR_O;
 
   output               CYC_O;
 
   input [31:0]  DAT_I;
 
   output [31:0]         DAT_O;
 
   input                ERR_I;
 
   input                RTY_I;
 
   output [3:0]  SEL_O;
 
   output               STB_O;
 
   output               WE_O;
 
 
 
   reg [31:0]            ADR_O;
 
   reg [3:0]             SEL_O;
 
   reg                  CYC_O;
 
   reg                  STB_O;
 
   reg                  WE_O;
 
   reg [31:0]            DAT_O;
 
 
 
   wire [15:0]           mem_sizes;      // determines the data width of an address range
 
   reg [31:0]            write_burst_buffer[0:7];
 
   reg [31:0]            read_burst_buffer[0:7];
 
 
 
   reg                  GO;
 
   integer              cycle_end;
 
   integer              address;
 
   integer              data;
 
   integer              selects;
 
   integer              write_flag;
 
 
 
   //
 
   // mem_sizes determines the data widths of memory space
 
   // The memory space is divided into eight regions. Each
 
   // region is controlled by a two bit field.
 
   //
 
   //    Bits
 
   //    00 = 8 bit memory space
 
   //    01 = 16 bit 
 
   //    10 = 32 bit
 
   //    11 = 64 bit (not supported in this model
 
   //
 
 
 
   assign               mem_sizes = 16'b00_01_10_11_00_01_10_11;
 
 
 
   function [1:0] data_width;
 
      input [31:0] adr;
 
      begin
 
         casex (adr[31:29])
 
           3'b000: data_width = mem_sizes[15:14];
 
           3'b001: data_width = mem_sizes[13:12];
 
           3'b010: data_width = mem_sizes[11:10];
 
           3'b011: data_width = mem_sizes[9:8];
 
           3'b100: data_width = mem_sizes[7:6];
 
           3'b101: data_width = mem_sizes[5:4];
 
           3'b110: data_width = mem_sizes[3:2];
 
           3'b111: data_width = mem_sizes[1:0];
 
           3'bxxx: data_width = 2'bxx;
 
         endcase // casex (adr[31:29])
 
      end
 
   endfunction
 
 
 
   always @(posedge CLK_I or posedge RST_I)
 
     begin
 
        if (RST_I)
 
          begin
 
             GO = 1'b0;
 
          end
 
     end
 
 
 
   // read single
 
   task rd;
 
      input [31:0] adr;
 
      output [31:0] result;
 
 
 
      begin
 
         cycle_end = 1;
 
         address = adr;
 
         selects = 255;
 
         write_flag = 0;
 
 
 
         GO <= 1;
 
         @(posedge CLK_I);
 
         GO <= 0;
 
 
 
         // wait for cycle to start
 
         while (~CYC_O)
 
           @(posedge CLK_I);
 
 
 
         // wait for cycle to end
 
         while (CYC_O)
 
           @(posedge CLK_I);
 
 
 
         result = data;
 
 
 
      end
 
   endtask // read
 
 
 
   task wr;
 
      input [31:0] adr;
 
      input [31:0] dat;
 
      input [3:0] sel;
 
      begin
 
         cycle_end = 1;
 
         address = adr;
 
         selects = sel;
 
         write_flag = 1;
 
         data = dat;
 
 
 
         GO <= 1;
 
         @(posedge CLK_I);
 
         GO <= 0;
 
 
 
         // wait for cycle to start
 
         while (~CYC_O)
 
           @(posedge CLK_I);
 
 
 
         // wait for cycle to end
 
         while (CYC_O)
 
           @(posedge CLK_I);
 
      end
 
   endtask // wr
 
 
 
   // block read
 
   task blkrd;
 
      input [31:0] adr;
 
      input end_flag;
 
      output [31:0] result;
 
 
 
      begin
 
         write_flag = 0;
 
         cycle_end = end_flag;
 
         address = adr;
 
         GO <= 1;
 
         @(posedge CLK_I);
 
         GO <= 0;
 
 
 
         while (~(ACK_I & STB_O))
 
           @(posedge CLK_I);
 
 
 
         result = data;
 
      end
 
   endtask // blkrd
 
 
 
   // block write
 
   task blkwr;
 
      input [31:0] adr;
 
      input [31:0] dat;
 
      input [3:0] sel;
 
      input end_flag;
 
      begin
 
         write_flag = 1;
 
         cycle_end = end_flag;
 
         address = adr;
 
         data = dat;
 
         selects = sel;
 
         GO <= 1;
 
         @(posedge CLK_I);
 
         GO <= 0;
 
 
 
         while (~(ACK_I & STB_O))
 
           @(posedge CLK_I);
 
 
 
      end
 
   endtask // blkwr
 
 
 
   // RMW
 
   task rmw;
 
      input [31:0] adr;
 
      input [31:0] dat;
 
      input [3:0] sel;
 
      output [31:0] result;
 
 
 
      begin
 
         // read phase
 
         write_flag = 0;
 
         cycle_end = 0;
 
         address = adr;
 
         GO <= 1;
 
         @(posedge CLK_I);
 
         GO <= 0;
 
 
 
         while (~(ACK_I & STB_O))
 
           @(posedge CLK_I);
 
 
 
         result = data;
 
 
 
         // write phase
 
         write_flag = 1;
 
         address = adr;
 
         selects = sel;
 
         GO <= 1;
 
         data <= dat;
 
         cycle_end <= 1;
 
         @(posedge CLK_I);
 
         GO <= 0;
 
 
 
         while (~(ACK_I & STB_O))
 
           @(posedge CLK_I);
 
 
 
      end
 
   endtask // rmw
 
 
 
   always @(posedge CLK_I)
 
     begin
 
        if (RST_I)
 
          ADR_O <= 32'h0000_0000;
 
        else
 
          ADR_O <= address;
 
     end
 
 
 
   always @(posedge CLK_I)
 
     begin
 
        if (RST_I | ERR_I | RTY_I)
 
          CYC_O <= 1'b0;
 
        else if ((cycle_end == 1) & ACK_I)
 
          CYC_O <= 1'b0;
 
        else if (GO | CYC_O)
 
          CYC_O <= 1'b1;
 
     end
 
 
 
   // stb control
 
   always @(posedge CLK_I)
 
     begin
 
        if (RST_I | ERR_I | RTY_I)
 
          STB_O <= 1'b0;
 
        else if (STB_O & ACK_I)
 
          STB_O <= 1'b0;
 
        else if (GO | STB_O)
 
          STB_O <= 1'b1;
 
     end
 
 
 
   // selects & data
 
   always @(posedge CLK_I)
 
     begin
 
        if (write_flag == 0) begin
 
           SEL_O <= 4'b1111;
 
           if (STB_O & ACK_I)
 
             data <= DAT_I;
 
        end
 
        else begin
 
           case (data_width(address))
 
             2'b00: begin
 
                SEL_O <= {3'b000, selects[0]};
 
                DAT_O <= {data[7:0], data[7:0], data[7:0], data[7:0]};
 
             end
 
             2'b01: begin
 
                SEL_O <= {2'b00, selects[1:0]};
 
                DAT_O <= {data[15:0], data[15:0]};
 
             end
 
             2'b10: begin
 
                SEL_O <= selects;
 
                DAT_O <= data;
 
             end
 
           endcase
 
        end
 
     end
 
 
 
   always @(posedge CLK_I)
 
     begin
 
        if (RST_I)
 
          WE_O <= 1'b0;
 
        else if (GO)
 
          WE_O <= write_flag;
 
     end
 
 
 
endmodule
 
 
 
 
 
 
 
 
 
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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