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

Subversion Repositories amber

[/] [amber/] [trunk/] [hw/] [vlog/] [amber25/] [a25_decode.v] - Diff between revs 20 and 35

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

Rev 20 Rev 35
Line 43... Line 43...
 
 
module a25_decode
module a25_decode
(
(
input                       i_clk,
input                       i_clk,
input       [31:0]          i_fetch_instruction,
input       [31:0]          i_fetch_instruction,
input                       i_access_stall,                 // stall all stages of the cpu at the same time
input                       i_core_stall,                   // stall all stages of the Amber core at the same time
input                       i_irq,                          // interrupt request
input                       i_irq,                          // interrupt request
input                       i_firq,                         // Fast interrupt request
input                       i_firq,                         // Fast interrupt request
input                       i_dabt,                         // data abort interrupt request
input                       i_dabt,                         // data abort interrupt request
input                       i_iabt,                         // instruction pre-fetch abort flag
input                       i_iabt,                         // instruction pre-fetch abort flag
input                       i_adex,                         // Address Exception
input                       i_adex,                         // Address Exception
Line 59... Line 59...
 
 
 
 
// --------------------------------------------------
// --------------------------------------------------
// Control signals to execute stage
// Control signals to execute stage
// --------------------------------------------------
// --------------------------------------------------
// output reg  [4:0]           o_read_data_alignment = 1'd0,  // 2 LSBs of read address used for calculating shift in ldrb ops
 
 
 
output reg  [31:0]          o_imm32 = 'd0,
output reg  [31:0]          o_imm32 = 'd0,
output reg  [4:0]           o_imm_shift_amount = 'd0,
output reg  [4:0]           o_imm_shift_amount = 'd0,
output reg                  o_shift_imm_zero = 'd0,
output reg                  o_shift_imm_zero = 'd0,
output reg  [3:0]           o_condition = 4'he,             // 4'he = al
output reg  [3:0]           o_condition = 4'he,             // 4'he = al
output reg                  o_decode_exclusive = 'd0,       // exclusive access request ( swap instruction )
output reg                  o_decode_exclusive = 'd0,       // exclusive access request ( swap instruction )
Line 164... Line 162...
 
 
// ========================================================
// ========================================================
// Internal signals
// Internal signals
// ========================================================
// ========================================================
wire    [31:0]         instruction;
wire    [31:0]         instruction;
 
wire    [3:0]          type;                    // regop, mem access etc.
wire                   instruction_iabt;        // abort flag, follows the instruction
wire                   instruction_iabt;        // abort flag, follows the instruction
wire                   instruction_adex;        // address exception flag, follows the instruction
wire                   instruction_adex;        // address exception flag, follows the instruction
wire    [31:0]         instruction_address;     // instruction virtual address, follows 
wire    [31:0]         instruction_address;     // instruction virtual address, follows 
                                                // the instruction
                                                // the instruction
wire    [7:0]          instruction_iabt_status; // abort status, follows the instruction
wire    [7:0]          instruction_iabt_status; // abort status, follows the instruction
wire    [1:0]          instruction_sel;
wire    [1:0]          instruction_sel;
reg     [3:0]          type;
 
wire    [3:0]          opcode;
wire    [3:0]          opcode;
wire    [7:0]          imm8;
wire    [7:0]          imm8;
wire    [31:0]         offset12;
wire    [31:0]         offset12;
wire    [31:0]         offset24;
wire    [31:0]         offset24;
wire    [4:0]          shift_imm;
wire    [4:0]          shift_imm;
Line 253... Line 251...
reg                    iabt_reg = 'd0;
reg                    iabt_reg = 'd0;
reg                    adex_reg = 'd0;
reg                    adex_reg = 'd0;
reg     [31:0]         fetch_address_r = 'd0;
reg     [31:0]         fetch_address_r = 'd0;
reg     [7:0]          abt_status_reg = 'd0;
reg     [7:0]          abt_status_reg = 'd0;
reg     [31:0]         fetch_instruction_r = 'd0;
reg     [31:0]         fetch_instruction_r = 'd0;
 
reg     [3:0]          fetch_instruction_type_r = 'd0;
reg     [31:0]         saved_current_instruction = 'd0;
reg     [31:0]         saved_current_instruction = 'd0;
 
reg     [3:0]          saved_current_instruction_type = 'd0;
reg                    saved_current_instruction_iabt = 'd0;          // access abort flag
reg                    saved_current_instruction_iabt = 'd0;          // access abort flag
reg                    saved_current_instruction_adex = 'd0;          // address exception
reg                    saved_current_instruction_adex = 'd0;          // address exception
reg     [31:0]         saved_current_instruction_address = 'd0;       // virtual address of abort instruction
reg     [31:0]         saved_current_instruction_address = 'd0;       // virtual address of abort instruction
reg     [7:0]          saved_current_instruction_iabt_status = 'd0;   // status of abort instruction
reg     [7:0]          saved_current_instruction_iabt_status = 'd0;   // status of abort instruction
reg     [31:0]         pre_fetch_instruction = 'd0;
reg     [31:0]         pre_fetch_instruction = 'd0;
 
reg     [3:0]          pre_fetch_instruction_type = 'd0;
reg                    pre_fetch_instruction_iabt = 'd0;              // access abort flag
reg                    pre_fetch_instruction_iabt = 'd0;              // access abort flag
reg                    pre_fetch_instruction_adex = 'd0;              // address exception
reg                    pre_fetch_instruction_adex = 'd0;              // address exception
reg     [31:0]         pre_fetch_instruction_address = 'd0;           // virtual address of abort instruction
reg     [31:0]         pre_fetch_instruction_address = 'd0;           // virtual address of abort instruction
reg     [7:0]          pre_fetch_instruction_iabt_status = 'd0;       // status of abort instruction
reg     [7:0]          pre_fetch_instruction_iabt_status = 'd0;       // status of abort instruction
reg     [31:0]         hold_instruction = 'd0;
reg     [31:0]         hold_instruction = 'd0;
 
reg     [3:0]          hold_instruction_type = 'd0;
reg                    hold_instruction_iabt = 'd0;                   // access abort flag
reg                    hold_instruction_iabt = 'd0;                   // access abort flag
reg                    hold_instruction_adex = 'd0;                   // address exception
reg                    hold_instruction_adex = 'd0;                   // address exception
reg     [31:0]         hold_instruction_address = 'd0;                // virtual address of abort instruction
reg     [31:0]         hold_instruction_address = 'd0;                // virtual address of abort instruction
reg     [7:0]          hold_instruction_iabt_status = 'd0;            // status of abort instruction
reg     [7:0]          hold_instruction_iabt_status = 'd0;            // status of abort instruction
 
 
Line 308... Line 310...
wire                   ldm_user_mode;
wire                   ldm_user_mode;
wire                   ldm_status_bits;
wire                   ldm_status_bits;
wire                   ldm_flags;
wire                   ldm_flags;
wire    [6:0]          load_rd_d1_nxt;
wire    [6:0]          load_rd_d1_nxt;
reg     [6:0]          load_rd_d1 = 'd0;  // MSB is the valid bit
reg     [6:0]          load_rd_d1 = 'd0;  // MSB is the valid bit
 
 
wire                   rn_valid;
wire                   rn_valid;
wire                   rm_valid;
wire                   rm_valid;
wire                   rs_valid;
wire                   rs_valid;
wire                   rd_valid;
wire                   rd_valid;
wire                   stm_valid;
wire                   stm_valid;
Line 391... Line 394...
assign instruction      =         instruction_sel == 2'd0 ? fetch_instruction_r       :
assign instruction      =         instruction_sel == 2'd0 ? fetch_instruction_r       :
                                  instruction_sel == 2'd1 ? saved_current_instruction :
                                  instruction_sel == 2'd1 ? saved_current_instruction :
                                  instruction_sel == 2'd3 ? hold_instruction          :
                                  instruction_sel == 2'd3 ? hold_instruction          :
                                                            pre_fetch_instruction     ;
                                                            pre_fetch_instruction     ;
 
 
 
assign type             =         instruction_sel == 2'd0 ? fetch_instruction_type_r       :
 
                                  instruction_sel == 2'd1 ? saved_current_instruction_type :
 
                                  instruction_sel == 2'd3 ? hold_instruction_type          :
 
                                                            pre_fetch_instruction_type     ;
 
 
// abort flag
// abort flag
assign instruction_iabt =         instruction_sel == 2'd0 ? iabt_reg                       :
assign instruction_iabt =         instruction_sel == 2'd0 ? iabt_reg                       :
                                  instruction_sel == 2'd1 ? saved_current_instruction_iabt :
                                  instruction_sel == 2'd1 ? saved_current_instruction_iabt :
                                  instruction_sel == 2'd3 ? hold_instruction_iabt          :
                                  instruction_sel == 2'd3 ? hold_instruction_iabt          :
                                                            pre_fetch_instruction_iabt     ;
                                                            pre_fetch_instruction_iabt     ;
Line 413... Line 421...
assign instruction_adex =         instruction_sel == 2'd0 ? adex_reg                       :
assign instruction_adex =         instruction_sel == 2'd0 ? adex_reg                       :
                                  instruction_sel == 2'd1 ? saved_current_instruction_adex :
                                  instruction_sel == 2'd1 ? saved_current_instruction_adex :
                                  instruction_sel == 2'd3 ? hold_instruction_adex          :
                                  instruction_sel == 2'd3 ? hold_instruction_adex          :
                                                            pre_fetch_instruction_adex     ;
                                                            pre_fetch_instruction_adex     ;
 
 
// Instruction Decode - Order is important!
 
always @*
 
    casez ({instruction[27:20], instruction[7:4]})
 
        12'b00010?001001 : type = SWAP;
 
        12'b000000??1001 : type = MULT;
 
        12'b00?????????? : type = REGOP;
 
        12'b01?????????? : type = TRANS;
 
        12'b100????????? : type = MTRANS;
 
        12'b101????????? : type = BRANCH;
 
        12'b110????????? : type = CODTRANS;
 
        12'b1110???????0 : type = COREGOP;
 
        12'b1110???????1 : type = CORTRANS;
 
        default:           type = SWI;
 
    endcase
 
 
 
 
 
// ========================================================
// ========================================================
// Fixed fields within the instruction
// Fixed fields within the instruction
// ========================================================
// ========================================================
 
 
Line 549... Line 542...
 
 
assign conflict       = conflict1 || conflict2;
assign conflict       = conflict1 || conflict2;
 
 
 
 
always @( posedge i_clk )
always @( posedge i_clk )
    if ( !i_access_stall )
    if ( !i_core_stall )
        begin
        begin
        conflict_r              <= conflict;
        conflict_r              <= conflict;
        instruction_execute_r   <= instruction_execute;
        instruction_execute_r   <= instruction_execute;
        rn_conflict1_r          <= rn_conflict1 && instruction_execute;
        rn_conflict1_r          <= rn_conflict1 && instruction_execute;
        rm_conflict1_r          <= rm_conflict1 && instruction_execute;
        rm_conflict1_r          <= rm_conflict1 && instruction_execute;
Line 786... Line 779...
                else
                else
                    reg_bank_wen_nxt = decode (instruction[15:12]);
                    reg_bank_wen_nxt = decode (instruction[15:12]);
                end
                end
 
 
            if ( !immediate_shift_op )
            if ( !immediate_shift_op )
 
                begin
                barrel_shift_function_nxt  = instruction[6:5];
                barrel_shift_function_nxt  = instruction[6:5];
 
                end
 
 
            if ( !immediate_shift_op )
            if ( !immediate_shift_op )
                barrel_shift_data_sel_nxt = 2'd2; // Shift value from Rm register
                barrel_shift_data_sel_nxt = 2'd2; // Shift value from Rm register
 
 
            if ( !immediate_shift_op && instruction[4] )
            if ( !immediate_shift_op && instruction[4] )
Line 1557... Line 1552...
 
 
// ========================================================
// ========================================================
// Register Update
// Register Update
// ========================================================
// ========================================================
always @ ( posedge i_clk )
always @ ( posedge i_clk )
    if ( !i_access_stall )
    if ( !i_core_stall )
        begin
        begin
        if (!conflict)
        if (!conflict)
            begin
            begin
            fetch_instruction_r         <= i_fetch_instruction;
            fetch_instruction_r         <= i_fetch_instruction;
 
            fetch_instruction_type_r    <= instruction_type(i_fetch_instruction);
            fetch_address_r             <= i_execute_iaddress;
            fetch_address_r             <= i_execute_iaddress;
            iabt_reg                    <= i_iabt;
            iabt_reg                    <= i_iabt;
            adex_reg                    <= i_adex;
            adex_reg                    <= i_adex;
            abt_status_reg              <= i_abt_status;
            abt_status_reg              <= i_abt_status;
            end
            end
Line 1628... Line 1624...
        end
        end
 
 
 
 
 
 
always @ ( posedge i_clk )
always @ ( posedge i_clk )
    if ( !i_access_stall )
    if ( !i_core_stall )
        begin
        begin
        // sometimes this is a pre-fetch instruction
        // sometimes this is a pre-fetch instruction
        // e.g. two ldr instructions in a row. The second ldr will be saved
        // e.g. two ldr instructions in a row. The second ldr will be saved
        // to the pre-fetch instruction register
        // to the pre-fetch instruction register
        // then when its decoded, a copy is saved to the saved_current_instruction
        // then when its decoded, a copy is saved to the saved_current_instruction
        // register
        // register
        if      ( type == MTRANS )
        if      ( type == MTRANS )
            begin
            begin
            saved_current_instruction              <= mtrans_instruction_nxt;
            saved_current_instruction              <= mtrans_instruction_nxt;
 
            saved_current_instruction_type         <= type;
            saved_current_instruction_iabt         <= instruction_iabt;
            saved_current_instruction_iabt         <= instruction_iabt;
            saved_current_instruction_adex         <= instruction_adex;
            saved_current_instruction_adex         <= instruction_adex;
            saved_current_instruction_address      <= instruction_address;
            saved_current_instruction_address      <= instruction_address;
            saved_current_instruction_iabt_status  <= instruction_iabt_status;
            saved_current_instruction_iabt_status  <= instruction_iabt_status;
            end
            end
        else if ( saved_current_instruction_wen )
        else if ( saved_current_instruction_wen )
            begin
            begin
            saved_current_instruction              <= instruction;
            saved_current_instruction              <= instruction;
 
            saved_current_instruction_type         <= type;
            saved_current_instruction_iabt         <= instruction_iabt;
            saved_current_instruction_iabt         <= instruction_iabt;
            saved_current_instruction_adex         <= instruction_adex;
            saved_current_instruction_adex         <= instruction_adex;
            saved_current_instruction_address      <= instruction_address;
            saved_current_instruction_address      <= instruction_address;
            saved_current_instruction_iabt_status  <= instruction_iabt_status;
            saved_current_instruction_iabt_status  <= instruction_iabt_status;
            end
            end
 
 
        if      ( pre_fetch_instruction_wen )
        if      ( pre_fetch_instruction_wen )
            begin
            begin
            pre_fetch_instruction                  <= fetch_instruction_r;
            pre_fetch_instruction                  <= fetch_instruction_r;
 
            pre_fetch_instruction_type             <= fetch_instruction_type_r;
            pre_fetch_instruction_iabt             <= iabt_reg;
            pre_fetch_instruction_iabt             <= iabt_reg;
            pre_fetch_instruction_adex             <= adex_reg;
            pre_fetch_instruction_adex             <= adex_reg;
            pre_fetch_instruction_address          <= fetch_address_r;
            pre_fetch_instruction_address          <= fetch_address_r;
            pre_fetch_instruction_iabt_status      <= abt_status_reg;
            pre_fetch_instruction_iabt_status      <= abt_status_reg;
            end
            end
 
 
 
 
 
        // TODO possible to use saved_current_instruction instead and save some regs?          
        hold_instruction              <= instruction;
        hold_instruction              <= instruction;
 
        hold_instruction_type         <= type;
        hold_instruction_iabt         <= instruction_iabt;
        hold_instruction_iabt         <= instruction_iabt;
        hold_instruction_adex         <= instruction_adex;
        hold_instruction_adex         <= instruction_adex;
        hold_instruction_address      <= instruction_address;
        hold_instruction_address      <= instruction_address;
        hold_instruction_iabt_status  <= instruction_iabt_status;
        hold_instruction_iabt_status  <= instruction_iabt_status;
        end
        end
 
 
 
 
 
 
always @ ( posedge i_clk )
always @ ( posedge i_clk )
    if ( !i_access_stall )
    if ( !i_core_stall )
        begin
        begin
        irq   <= i_irq;
        irq   <= i_irq;
        firq  <= i_firq;
        firq  <= i_firq;
 
 
        if ( control_state == INT_WAIT1 && o_status_bits_mode == SVC )
        if ( control_state == INT_WAIT1 && o_status_bits_mode == SVC )
Line 1700... Line 1702...
 
 
`include "debug_functions.v"
`include "debug_functions.v"
 
 
a25_decompile  u_decompile (
a25_decompile  u_decompile (
    .i_clk                      ( i_clk                            ),
    .i_clk                      ( i_clk                            ),
    .i_access_stall             ( i_access_stall                   ),
    .i_core_stall               ( i_core_stall                     ),
    .i_instruction              ( instruction                      ),
    .i_instruction              ( instruction                      ),
    .i_instruction_valid        ( instruction_valid &&!conflict    ),
    .i_instruction_valid        ( instruction_valid &&!conflict    ),
    .i_instruction_execute      ( instruction_execute              ),
    .i_instruction_execute      ( instruction_execute              ),
    .i_instruction_address      ( instruction_address              ),
    .i_instruction_address      ( instruction_address              ),
    .i_interrupt                ( {3{interrupt}} & next_interrupt  ),
    .i_interrupt                ( {3{interrupt}} & next_interrupt  ),

powered by: WebSVN 2.1.0

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