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

Subversion Repositories xulalx25soc

[/] [xulalx25soc/] [trunk/] [rtl/] [wbuexec.v] - Diff between revs 59 and 109

Show entire file | Details | Blame | View Log

Rev 59 Rev 109
Line 1... Line 1...
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
// Filename:    wbuexec.v
// Filename:    wbuexec.v
//
//
// Project:     XuLA2 board
// Project:     FPGA library
//
//
// Purpose:     This is the part of the USB-JTAG to wishbone conversion that
// Purpose:     This is the part of the USB-JTAG to wishbone conversion that
//              actually conducts a wishbone transaction.  Transactions are
//              actually conducts a wishbone transaction.  Transactions are
//      requested via codewords that come in, and the results recorded on
//      requested via codewords that come in, and the results recorded on
//      codewords that are sent out.  Compression and/or decompression, coding
//      codewords that are sent out.  Compression and/or decompression, coding
Line 50... Line 50...
        // The command inputs
        // The command inputs
        input                   i_stb;
        input                   i_stb;
        input           [35:0]   i_codword;
        input           [35:0]   i_codword;
        output  wire            o_busy;
        output  wire            o_busy;
        // Wishbone outputs
        // Wishbone outputs
        output  wire            o_wb_cyc, o_wb_stb;
        output  reg             o_wb_cyc;
 
        output  reg             o_wb_stb;
        output  reg             o_wb_we;
        output  reg             o_wb_we;
        output  reg     [31:0]   o_wb_addr, o_wb_data;
        output  reg     [31:0]   o_wb_addr, o_wb_data;
        // Wishbone inputs
        // Wishbone inputs
        input                   i_wb_ack, i_wb_stall, i_wb_err;
        input                   i_wb_ack, i_wb_stall, i_wb_err;
        input           [31:0]   i_wb_data;
        input           [31:0]   i_wb_data;
Line 77... Line 78...
                                &&(i_codword[35:30] != 6'h2e));
                                &&(i_codword[35:30] != 6'h2e));
 
 
        reg     [2:0]    wb_state;
        reg     [2:0]    wb_state;
        reg     [9:0]    r_acks_needed, r_len;
        reg     [9:0]    r_acks_needed, r_len;
        reg     r_inc, r_new_addr, last_read_request, last_ack, zero_acks;
        reg     r_inc, r_new_addr, last_read_request, last_ack, zero_acks;
 
        reg     single_read_request;
 
 
        initial r_new_addr = 1'b1;
        initial r_new_addr = 1'b1;
        initial wb_state = `WB_IDLE;
        initial wb_state = `WB_IDLE;
        initial o_stb = 1'b0;
        initial o_stb = 1'b0;
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (i_rst)
                if (i_rst)
                begin
                begin
                        wb_state <= `WB_IDLE;
                        wb_state <= `WB_IDLE;
                        o_stb <= 1'b1;
                        o_stb <= 1'b1;
                        o_codword <= { 6'h3, i_wb_data[29:0] };
                        o_codword <= { 6'h3, i_wb_data[29:0] }; // BUS Reset
 
                        o_wb_cyc <= 1'b0;
 
                        o_wb_stb <= 1'b0;
                end else case(wb_state)
                end else case(wb_state)
                `WB_IDLE: begin
                `WB_IDLE: begin
 
                        o_wb_cyc <= 1'b0;
 
                        o_wb_stb <= 1'b0;
                        // Now output codewords while we're idle,
                        // Now output codewords while we're idle,
                        //    ... unless we get an address command (later).
                        //    ... unless we get an address command (later).
                        o_stb    <= 1'b0;
                        o_stb    <= 1'b0;
 
 
                        // The new instruction.  The following
                        // The new instruction.  The following
Line 125... Line 131...
                                // Do we need to broadcast a new address?
                                // Do we need to broadcast a new address?
                                // r_new_addr <= 1'b0;
                                // r_new_addr <= 1'b0;
                                // 
                                // 
                                casez(i_codword[35:32])
                                casez(i_codword[35:32])
                                4'b0000: begin // Set a new (arbitrary) address
                                4'b0000: begin // Set a new (arbitrary) address
                                        r_new_addr <= 1'b1;
                                        // r_new_addr <= 1'b1;
                                        o_wb_addr <= i_codword[31:0];
                                        o_wb_addr <= i_codword[31:0]; //w_cod_data
                                        end
                                        end
                                4'b001?: begin // Set a new relative address
                                4'b001?: begin // Set a new relative address
                                        r_new_addr <= 1'b1;
                                        // r_new_addr <= 1'b1;
                                        o_wb_addr <= o_wb_addr
                                        o_wb_addr <= o_wb_addr // + w_cod_data;
 
 
                                                + { i_codword[32:31], i_codword[29:0] };
                                                + { i_codword[32:31], i_codword[29:0] };
                                        end
                                        end
                                4'b01??: begin // Start a write transaction,
                                4'b01??: begin // Start a write transaction,
                                        // address is alrdy set
                                        // address is alrdy set
                                        r_new_addr <= 1'b1;
                                        // r_new_addr <= 1'b1;
                                        wb_state <= `WB_WRITE_REQUEST;
                                        wb_state <= `WB_WRITE_REQUEST;
 
                                        o_wb_cyc <= 1'b1;
 
                                        o_wb_stb <= 1'b1;
                                        end
                                        end
                                4'b11??: begin // Start a vector read
                                4'b11??: begin // Start a vector read
                                        // Address is already set ...
                                        // Address is already set ...
                                        // This also depends upon the decoder working
                                        // This also depends upon the decoder working
                                        if (r_new_addr)
                                        if (r_new_addr)
                                                o_stb <= 1'b1;
                                                o_stb <= 1'b1;
                                        wb_state <= `WB_READ_REQUEST;
                                        wb_state <= `WB_READ_REQUEST;
 
                                        o_wb_cyc <= 1'b1;
 
                                        o_wb_stb <= 1'b1;
                                        end
                                        end
                                default:
                                default:
                                        ;
                                        ;
                                endcase
                                endcase
                        end end
                        end end
                `WB_READ_REQUEST: begin
                `WB_READ_REQUEST: begin
                        r_new_addr <= 1'b0;
                        o_wb_cyc <= 1'b1;
 
                        o_wb_stb <= 1'b1;
 
 
                        if (i_wb_err)
                        if (i_wb_err)
                                wb_state <= `WB_IDLE;
                                wb_state <= `WB_IDLE;
 
 
                        o_stb <= (i_wb_err)||(i_wb_ack);
                        o_stb <= (i_wb_err)||(i_wb_ack);
 
 
                        if (i_wb_err)
                        if (i_wb_err) // Bus Error
                                o_codword <= { 6'h5, i_wb_data[29:0] };
                                o_codword <= { 6'h5, i_wb_data[29:0] };
                        else
                        else // Read data on ack
                                o_codword <= { 3'h7, i_wb_data[31:30], r_inc,
                                o_codword <= { 3'h7, i_wb_data[31:30], r_inc,
                                        i_wb_data[29:0] };
                                        i_wb_data[29:0] };
 
 
                        if ((r_inc)&&(~i_wb_stall))
                        if ((r_inc)&&(~i_wb_stall))
                                o_wb_addr <= o_wb_addr + 32'h001;
                                o_wb_addr <= o_wb_addr + 32'h001;
 
 
 
 
                        if (~i_wb_stall) // Deal with the strobe line
                        if (~i_wb_stall) // Deal with the strobe line
                        begin // Strobe was accepted, busy should be '1' here
                        begin // Strobe was accepted, busy should be '1' here
                                if (last_read_request) // (r_len != 0) // read
                                if ((single_read_request)||(last_read_request)) // (r_len != 0) // read
 
                                begin
                                        wb_state <= `WB_ACK;
                                        wb_state <= `WB_ACK;
 
                                        o_wb_stb <= 1'b0;
 
                                end
                        end end
                        end end
                `WB_WRITE_REQUEST: begin
                `WB_WRITE_REQUEST: begin
                        r_new_addr <= 1'b0;
                        o_wb_cyc <= 1'b1;
 
                        o_wb_stb <= 1'b1;
 
                        //
 
 
                        if (i_wb_err)
                        if (i_wb_err) // Bus Err
                                o_codword <= { 6'h5, i_wb_data[29:0] };
                                o_codword <= { 6'h5, i_wb_data[29:0] };
                        else
                        else // Write acknowledgement
                                o_codword <= { 6'h2, i_wb_data[29:0] };
                                o_codword <= { 6'h2, i_wb_data[29:0] };
 
 
                        if ((r_inc)&&(~i_wb_stall))
                        if ((r_inc)&&(~i_wb_stall))
                                o_wb_addr <= o_wb_addr + 32'h001;
                                o_wb_addr <= o_wb_addr + 32'h001;
 
 
Line 194... Line 211...
 
 
                        if (i_wb_err)
                        if (i_wb_err)
                        begin
                        begin
                                wb_state <= `WB_FLUSH_WRITE_REQUESTS;
                                wb_state <= `WB_FLUSH_WRITE_REQUESTS;
                                //
                                //
 
                                o_wb_cyc <= 1'b0;
 
                                o_wb_stb <= 1'b0;
                        end else if (~i_wb_stall)
                        end else if (~i_wb_stall)
 
                        begin
                                wb_state <= `WB_WAIT_ON_NEXT_WRITE;
                                wb_state <= `WB_WAIT_ON_NEXT_WRITE;
                        end
                                o_wb_stb <= 1'b0;
 
                        end end
                `WB_ACK: begin
                `WB_ACK: begin
                        r_new_addr <= 1'b0;
                        o_wb_cyc <= 1'b1;
 
                        o_wb_stb <= 1'b0;
                        //
                        //
                        // No strobes are being sent out.  No further
                        // No strobes are being sent out.  No further
                        // bus transactions are requested.  We only need
                        // bus transactions are requested.  We only need
                        // to finish processing the last one(s) by waiting
                        // to finish processing the last one(s) by waiting
                        // for (and recording?) their acks.
                        // for (and recording?) their acks.
                        //
                        //
                        // Process acknowledgements
                        // Process acknowledgements
                        if (i_wb_err)
                        if (i_wb_err) // Bus error
                                o_codword <= { 6'h5, i_wb_data[29:0] };
                                o_codword <= { 6'h5, i_wb_data[29:0] };
                        else
                        else // Read data
                                o_codword <= { 3'h7, i_wb_data[31:30], r_inc,
                                o_codword <= { 3'h7, i_wb_data[31:30], r_inc,
                                        i_wb_data[29:0] };
                                        i_wb_data[29:0] };
 
 
                        // Return a read result, or (possibly) an error
                        // Return a read result, or (possibly) an error
                        // notification
                        // notification
                        o_stb <= (((i_wb_ack)&&(~o_wb_we)) || (i_wb_err));
                        o_stb <= (((i_wb_ack)&&(~o_wb_we)) || (i_wb_err));
 
 
                        if (((last_ack)&&(i_wb_ack))||(zero_acks)||(i_wb_err))
                        if (((last_ack)&&(i_wb_ack))||(zero_acks)||(i_wb_err))
 
                        begin
 
                                o_wb_cyc <= 1'b0;
                                wb_state <= `WB_IDLE;
                                wb_state <= `WB_IDLE;
                        end
                        end end
                `WB_WAIT_ON_NEXT_WRITE: begin
                `WB_WAIT_ON_NEXT_WRITE: begin
                        r_new_addr <= 1'b0;
 
 
 
                        o_codword <= { 6'h5, i_wb_data[29:0] };
                        o_codword <= { 6'h5, i_wb_data[29:0] };
                        o_stb <= (i_wb_err)||(w_new_err);
                        o_stb <= (i_wb_err)||(w_new_err);
 
 
                        o_wb_data <= w_cod_data;
                        o_wb_data <= w_cod_data;
 
                        o_wb_cyc <= 1'b1;
 
                        o_wb_stb <= 1'b0;
 
 
                        if (w_new_err) // Something other than a write or EOW
                        if (w_new_err) // Something other than a write or EOW
 
                        begin
 
                                o_wb_cyc <= 1'b0;
                                wb_state <= `WB_IDLE;
                                wb_state <= `WB_IDLE;
                        else if (i_wb_err) // Bus returns an error
                        end else if (i_wb_err) // Bus returns an error
 
                        begin
 
                                o_wb_cyc <= 1'b0;
                                wb_state <= `WB_FLUSH_WRITE_REQUESTS;
                                wb_state <= `WB_FLUSH_WRITE_REQUESTS;
 
                        end
                        else if (w_newwr) // Need to make a new write request
                        else if (w_newwr) // Need to make a new write request
 
                        begin
                                wb_state <= `WB_WRITE_REQUEST;
                                wb_state <= `WB_WRITE_REQUEST;
 
                                o_wb_stb <= 1'b1;
 
                        end
                        else if (w_eow) // All done writing, wait for last ack
                        else if (w_eow) // All done writing, wait for last ack
                                wb_state <= `WB_ACK;
                                wb_state <= `WB_ACK;
                        end
                        end
                `WB_FLUSH_WRITE_REQUESTS: begin
                `WB_FLUSH_WRITE_REQUESTS: begin
                        // We come in here after an error within a write
                        // We come in here after an error within a write
Line 245... Line 278...
                        // to idle.
                        // to idle.
                        //
                        //
                        // In the off chance that we are in here in error, or
                        // In the off chance that we are in here in error, or
                        // out of sync, we'll transition to WB_IDLE and just
                        // out of sync, we'll transition to WB_IDLE and just
                        // issue a second error token.
                        // issue a second error token.
                        r_new_addr <= 1'b0;
 
 
 
 
                        o_wb_cyc <= 1'b0;
 
                        o_wb_stb <= 1'b0;
                        o_codword <= { 6'h5, i_wb_data[29:0] };
                        o_codword <= { 6'h5, i_wb_data[29:0] };
                        o_stb <= (w_new_err);
                        o_stb <= (w_new_err);
 
 
                        if ((w_eow)||(w_new_err))
                        if ((w_eow)||(w_new_err))
                                wb_state <= `WB_IDLE;
                                wb_state <= `WB_IDLE;
                        end
                        end
                default: begin
                default: begin
                        o_stb <= 1'b1;
                        o_stb <= 1'b1;
                        o_codword <= { 6'h3, i_wb_data[29:0] };
                        o_codword <= { 6'h3, i_wb_data[29:0] };
                        wb_state <= `WB_IDLE;
                        wb_state <= `WB_IDLE;
 
                        o_wb_cyc <= 1'b0;
 
                        o_wb_stb <= 1'b0;
                        end
                        end
                endcase
                endcase
 
 
        assign o_busy = (wb_state != `WB_IDLE)
        assign o_busy = (wb_state != `WB_IDLE)
                        &&(wb_state != `WB_WAIT_ON_NEXT_WRITE)
                        &&(wb_state != `WB_WAIT_ON_NEXT_WRITE)
                        &&(wb_state != `WB_FLUSH_WRITE_REQUESTS);
                        &&(wb_state != `WB_FLUSH_WRITE_REQUESTS);
        assign o_wb_cyc = (wb_state == `WB_READ_REQUEST)
        //assign o_wb_cyc = (wb_state == `WB_READ_REQUEST)
                        ||(wb_state == `WB_WRITE_REQUEST)
                        //||(wb_state == `WB_WRITE_REQUEST)
                        ||(wb_state == `WB_ACK)
                        //||(wb_state == `WB_ACK)
                        ||(wb_state == `WB_WAIT_ON_NEXT_WRITE);
                        //||(wb_state == `WB_WAIT_ON_NEXT_WRITE);
        assign o_wb_stb = (wb_state == `WB_READ_REQUEST)
        //assign o_wb_stb = (wb_state == `WB_READ_REQUEST)
                                ||(wb_state == `WB_WRITE_REQUEST);
        //                      ||(wb_state == `WB_WRITE_REQUEST);
 
 
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (wb_state == `WB_IDLE)
                if (i_rst)
 
                        r_new_addr <= 1'b1;
 
                else if ((~o_wb_cyc)&&(i_stb)&&(~i_codword[35]))
 
                        r_new_addr <= 1'b1;
 
                else if (o_wb_cyc)
 
                        r_new_addr <= 1'b0;
 
 
 
        always @(posedge i_clk)
 
                if (~o_wb_cyc)
                        r_acks_needed <= 10'h00; // (i_codword[35])?i_codword[9:0]:10'h00;
                        r_acks_needed <= 10'h00; // (i_codword[35])?i_codword[9:0]:10'h00;
                else if ((o_wb_stb)&&(~i_wb_stall)&&(~i_wb_ack))
                else if ((o_wb_stb)&&(~i_wb_stall)&&(~i_wb_ack))
                        r_acks_needed <= r_acks_needed + 10'h01;
                        r_acks_needed <= r_acks_needed + 10'h01;
                else if (((~o_wb_stb)||(i_wb_stall))&&(i_wb_ack))
                else if (((~o_wb_stb)||(i_wb_stall))&&(i_wb_ack))
                        r_acks_needed <= r_acks_needed - 10'h01;
                        r_acks_needed <= r_acks_needed - 10'h01;
 
 
        always @(posedge i_clk)
        always @(posedge i_clk)
                last_ack <= (~o_wb_stb)&&(r_acks_needed == 10'h01);
                last_ack <= (~o_wb_stb)&&(r_acks_needed == 10'h01)
 
                                ||(o_wb_stb)&&(r_acks_needed == 10'h00);
 
 
        always @(posedge i_clk)
        always @(posedge i_clk)
                zero_acks <= (~o_wb_stb)&&(r_acks_needed == 10'h00);
                zero_acks <= (~o_wb_stb)&&(r_acks_needed == 10'h00);
 
 
        always @(posedge i_clk)
        always @(posedge i_clk)
                if ((wb_state == `WB_IDLE)&&(i_codword[35:34] == 2'b11))
                if (~o_wb_cyc) // &&(i_codword[35:34] == 2'b11))
                        r_len <= i_codword[9:0] - 10'h01;
                        r_len <= i_codword[9:0];
                else if ((o_wb_stb)&&(~i_wb_stall)&&(|r_len))
                else if ((o_wb_stb)&&(~i_wb_stall)&&(|r_len))
                        r_len <= r_len - 10'h01;
                        r_len <= r_len - 10'h01;
 
 
        always @(posedge i_clk)
        always @(posedge i_clk)
                last_read_request <= (r_len[9:0] == 10'h000);
        begin
 
                single_read_request <= (~o_wb_cyc)&&(i_codword[9:0] == 10'h01);
 
                // When there is one read request left, it will be the last one
 
                // will be the last one
 
                last_read_request <= (o_wb_stb)&&(r_len[9:2] == 8'h00)
 
                        &&((~r_len[1])
 
                                ||((~r_len[0])&&(~i_wb_stall)));
 
        end
 
 
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.