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

Subversion Repositories xulalx25soc

[/] [xulalx25soc/] [trunk/] [rtl/] [wbucompress.v] - Diff between revs 43 and 109

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 43 Rev 109
Line 1... Line 1...
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
// Filename:    wbucompress.v
// Filename:    wbucompress.v
//
//
// Project:     XuLA2 board
// Project:     FPGA library
//
//
// Purpose:     When reading many words that are identical, it makes no sense
// Purpose:     When reading many words that are identical, it makes no sense
//              to spend the time transmitting the same thing over and over
//              to spend the time transmitting the same thing over and over
//      again, especially on a slow channel.  Hence this routine uses a table
//      again, especially on a slow channel.  Hence this routine uses a table
//      lookup to see if the word to be transmitted was one from the recent
//      lookup to see if the word to be transmitted was one from the recent
Line 24... Line 24...
// Creator:     Dan Gisselquist, Ph.D.
// Creator:     Dan Gisselquist, Ph.D.
//              Gisselquist Technology, LLC
//              Gisselquist Technology, LLC
//
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
// Copyright (C) 2015, Gisselquist Technology, LLC
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
//
//
// This program is free software (firmware): you can redistribute it and/or
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of  the GNU General Public License as published
// modify it under the terms of  the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or (at
// by the Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
// your option) any later version.
Line 131... Line 131...
        // table.  And the first part of that is keeping track of what address
        // table.  And the first part of that is keeping track of what address
        // to write into the compression table, and whether or not the entire
        // to write into the compression table, and whether or not the entire
        // table is full or not.  This logic follows:
        // table is full or not.  This logic follows:
        //
        //
        reg     [(TBITS-1):0]    tbl_addr;
        reg     [(TBITS-1):0]    tbl_addr;
        reg                     r_compressed, tbl_filled;
        reg                     tbl_filled;
        // First part, write the compression table
        // First part, write the compression table
        always @(posedge i_clk)
        always @(posedge i_clk)
                // If we send a new address, then reset the table to empty
                // If we send a new address, then reset the table to empty
                if (w_accepted)
                if (w_accepted)
                begin
                begin
Line 173... Line 173...
        // Now that we have a working table, can we use it?
        // Now that we have a working table, can we use it?
        // On any new word, we'll start looking through our codewords.
        // On any new word, we'll start looking through our codewords.
        // If we find any that matches, we're there.  We might (or might not)
        // If we find any that matches, we're there.  We might (or might not)
        // make it through the table first.  That's irrelevant.  We just look
        // make it through the table first.  That's irrelevant.  We just look
        // while we can.
        // while we can.
 
        reg                     tbl_match, nxt_match; // <= (nxt_rd_addr == tbl_addr);
        reg     [(TBITS-1):0]    rd_addr;
        reg     [(TBITS-1):0]    rd_addr;
        wire    [(TBITS-1):0]    nxt_rd_addr;
        reg     [(TBITS-1):0]    nxt_rd_addr;
        assign  nxt_rd_addr = rd_addr - { {(TBITS-1){1'b0}}, 1'b1 };
 
        initial rd_addr = 0;
        initial rd_addr = 0;
 
        initial tbl_match = 0;
        always @(posedge i_clk)
        always @(posedge i_clk)
 
        begin
 
                nxt_match <= ((nxt_rd_addr-tbl_addr)=={{(TBITS-1){1'b0}},1'b1});
                if ((w_accepted)||(~a_stb))
                if ((w_accepted)||(~a_stb))
 
                begin
                        // Keep in mind, if a write was just accepted, then
                        // Keep in mind, if a write was just accepted, then
                        // rd_addr will need to be reset on the next clock
                        // rd_addr will need to be reset on the next clock
                        // when (~a_stb).  Hence this must be a two clock
                        // when (~a_stb).  Hence this must be a two clock
                        // update
                        // update
                        rd_addr <= tbl_addr + {(TBITS){1'b1}};
                        rd_addr <= tbl_addr + {(TBITS){1'b1}};
                else if ((nxt_rd_addr != tbl_addr)&&(~match)
                        nxt_rd_addr = tbl_addr + { {(TBITS-1){1'b1}}, 1'b0 };
 
                        tbl_match <= 1'b0;
 
                end else if ((~tbl_match)&&(~match)
                                &&((~nxt_rd_addr[TBITS-1])||(tbl_filled)))
                                &&((~nxt_rd_addr[TBITS-1])||(tbl_filled)))
 
                begin
                        rd_addr <= nxt_rd_addr;
                        rd_addr <= nxt_rd_addr;
 
                        nxt_rd_addr = nxt_rd_addr - { {(TBITS-1){1'b0}}, 1'b1 };
 
                        tbl_match <= nxt_match;
 
                end
 
        end
 
 
 
        reg     [1:0]            pmatch;
 
        reg                     dmatch, // Match, on clock 'd'
 
                                vaddr;  // Was the address valid then?
        reg     [(DW-1):0]       cword;
        reg     [(DW-1):0]       cword;
        reg     [(TBITS-1):0]    caddr;
        reg     [(TBITS-1):0]    caddr, daddr, maddr;
        always @(posedge i_clk)
        always @(posedge i_clk)
        begin
        begin
                cword <= compression_tbl[rd_addr];
                cword <= compression_tbl[rd_addr];
                caddr <= rd_addr;
                caddr <= rd_addr;
 
 
 
                dmatch <= (cword == { r_word[32:31], r_word[29:0] });
 
                daddr  <= caddr;
 
                maddr  <= tbl_addr - caddr;
 
 
 
                vaddr <= ( {1'b0, caddr} < {tbl_filled, tbl_addr} )
 
                        &&(caddr != tbl_addr);
        end
        end
 
 
 
        always @(posedge i_clk)
 
                if ((w_accepted)||(~a_stb))
 
                        pmatch <= 0; // rd_addr is set on this clock
 
                else
 
                        // cword is set on the next clock, pmatch = 3'b001
 
                        // dmatch is set on the next clock, pmatch = 3'b011
 
                        pmatch <= { pmatch[0], 1'b1 };
 
 
        reg             match;
        reg             match;
        reg     [9:0]    matchaddr;
        reg     [9:0]    matchaddr;
        always @(posedge i_clk)
        always @(posedge i_clk)
                if((w_accepted)||(~a_stb)||(~r_stb))// Reset upon any write
                if((w_accepted)||(~a_stb)||(~r_stb))// Reset upon any write
                        match <= 1'b0;
                        match <= 1'b0;
                else if (~match)
                else if (~match)
                begin
                begin
                        // To be a match, the table must not be empty,
                        // To be a match, the table must not be empty,
                        match <= (({1'b0, caddr } < {tbl_filled, tbl_addr}))
                        match <= (vaddr)&&(dmatch)&&(r_word[35:33]==3'b111)
                                        // the word we are matching to must be
                                        &&(pmatch == 2'b11);
                                        // in the form of a read command
                end
                                        &&(r_word[35:33] == 3'b111)
 
                                        // And the word in the table must be
        reg     zmatch, hmatch, fmatch;
                                        // identical to the word we are about
        always @(posedge i_clk)
                                        // to send.
                if (~match)
                                        &&(cword == { r_word[32:31], r_word[29:0] });
                begin
                        matchaddr <= tbl_addr-caddr;
                        matchaddr <= maddr;
 
                        fmatch    <= (maddr < 10'h521);
 
                        zmatch    <= (maddr == 10'h1);
 
                        hmatch    <= (maddr < 10'd10);
                end
                end
 
 
        // Did we find something?
        // Did we find something?
        wire    [(TBITS-1):0]    adr_diff;
        wire    [(TBITS-1):0]    adr_diff;
        wire    [9:0]            adr_dbld;
        wire    [9:0]            adr_dbld;
        wire    [2:0]            adr_hlfd;
        wire    [2:0]            adr_hlfd;
        assign  adr_diff = matchaddr;
        assign  adr_diff = matchaddr;
        assign  adr_hlfd = matchaddr[2:0]- 3'd2;
        assign  adr_hlfd = matchaddr[2:0]- 3'd2;
        assign  adr_dbld = matchaddr- 10'd10;
        assign  adr_dbld = matchaddr- 10'd10;
        initial r_compressed = 1'b0;
 
        reg     [(CW-1):0]       r_cword; // Record our result
        reg     [(CW-1):0]       r_cword; // Record our result
        always @(posedge i_clk)
        always @(posedge i_clk)
        begin
        begin
                if ((~a_stb)||(~r_stb)||(w_accepted))//Reset whenever word gets written
                if ((~a_stb)||(~r_stb)||(w_accepted))//Reset whenever word gets written
                        r_compressed <= 1'b0; // to our output
 
                else if (r_compressed)//Already compressed, wait 'til sent
 
                        ;
 
                else if ((match)&&(matchaddr < 10'd521)) // &&(r_word == a_addrword))
 
                begin
                begin
                        if (matchaddr == 10'h1)
                        r_cword <= r_word;
 
                end else if ((match)&&(fmatch)) // &&(r_word == a_addrword))
 
                begin
 
                        r_cword <= r_word;
 
                        if (zmatch) // matchaddr == 1
                                r_cword[35:30] <= { 5'h3, r_word[30] };
                                r_cword[35:30] <= { 5'h3, r_word[30] };
                        else if (adr_diff < 10'd10)
                        else if (hmatch) // 2 <= matchaddr <= 9
                                r_cword[35:30] <= { 2'b10, adr_hlfd, r_word[30] };
                                r_cword[35:30] <= { 2'b10, adr_hlfd, r_word[30] };
                        else // if (adr_diff < 10'd521)
                        else // if (adr_diff < 10'd521)
                                r_cword[35:24] <= { 2'b01, adr_dbld[8:6],
                                r_cword[35:24] <= { 2'b01, adr_dbld[8:6],
                                                r_word[30], adr_dbld[5:0] };
                                                r_word[30], adr_dbld[5:0] };
                        r_compressed <= 1'b1;
 
                end else
                end else
                        r_cword <= r_word;
                        r_cword <= r_word;
        end
        end
 
 
        // Can we do this without a clock delay?
        // Can we do this without a clock delay?
        assign  o_stb = a_stb;
        assign  o_stb = a_stb;
        assign  o_cword = (r_compressed)?(r_cword):(a_addrword);
        assign  o_cword = (r_stb)?(r_cword):(a_addrword);
endmodule
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.