3.レジスタ


H8のレジスタ構成です。
アクセスとしては、8ビットレジスタ16本(R0L-R7H)、16ビットレジスタ16本(R0-R7,E0-E7)、32ビットレジスタ(ER0-ER7)8本としてアクセスできます。ER7は、スタックポインタとして暗黙的に使用されます。

レジスタは、その名の通り、記憶素子です。素直に仕様を記述して行きます。1パックとしてreg_file モジュールとして記述します。ここでやや面倒なのは、BYTE_ACCESS,WORD_ACCESS,LONG_ACCESSがあることです。それぞれのアクセスに対し、WriteやReadを適切にアレンジしなくてはいけません。

入力1ポート(32ビット、ALUの出力または、Effective_Addressの出力選択)、出力3ポート(LEFT,RIGHT32ビットx2 ALU用、EA用)として記述します。

レジスタのアドレス指定(Register Field)は、インストラクションレジスタ(32ビット、(64ビットを一回でフェッチするがその上位32ビット)中の4ビット)で指定されますが、命令毎にその位置が違うので、MUXで位置を選択します。一般に、これらの制御線がマイクロコードになります。

`include "define.h"
//Jun.3.2004 add 3rd output port
module reg_file(clock,sync_reset,irhword,left_address_sel,right_address_sel,write_address_sel,
                    access_mode,reg_write,alu_out,ea,reg_left_out,reg_right_out,insel,left_address_out,ea_reg_address);
        input clock,sync_reset;
          input [31:0] irhword;
          input [1:0] left_address_sel,right_address_sel;
          input [2:0] write_address_sel;
          input [1:0] access_mode;
          input reg_write;
          input insel;
          input [31:0] alu_out;
          input [23:0] ea;
          output [31:0] reg_left_out,reg_right_out; // output data file
          output [31:0] left_address_out;//For EA Address
          input [2:0] ea_reg_address;//May.30.2004
       
        
        wire write0,write1,write2,write3,write4,write5,write6,write7;
        wire high_access;
          wire [31:0] ER0,ER1,ER2,ER3,ER4,ER5,ER6,ER7,Y0,Y1,Y2;
          wire [3:0] input_address,reg_out0_address,reg_out1_address;
        
          wire [3:0] IR0H=irhword[31:28];
          wire [3:0] IR0L=irhword[27:24];

          wire [3:0] IR1H=irhword[23:20];
          wire [3:0] IR1L=irhword[19:16];
                
          wire [3:0] IR3H=irhword[7:4];
          wire [3:0] IR3L=irhword[3:0];

          wire [31:0] i32=insel==`ALU_OUT_SEL ? alu_out:{8'h00, ea};


reg32   reg32_0(.clock(clock),.sync_reset(sync_reset),.access_bytes(access_mode),.i32(i32),.R32(ER0),.write(write0),.high_access(high_access));
reg32   reg32_1(.clock(clock),.sync_reset(sync_reset),.access_bytes(access_mode),.i32(i32),.R32(ER1),.write(write1),.high_access(high_access));
reg32   reg32_2(.clock(clock),.sync_reset(sync_reset),.access_bytes(access_mode),.i32(i32),.R32(ER2),.write(write2),.high_access(high_access));
reg32   reg32_3(.clock(clock),.sync_reset(sync_reset),.access_bytes(access_mode),.i32(i32),.R32(ER3),.write(write3),.high_access(high_access));
reg32   reg32_4(.clock(clock),.sync_reset(sync_reset),.access_bytes(access_mode),.i32(i32),.R32(ER4),.write(write4),.high_access(high_access));
reg32   reg32_5(.clock(clock),.sync_reset(sync_reset),.access_bytes(access_mode),.i32(i32),.R32(ER5),.write(write5),.high_access(high_access));
reg32   reg32_6(.clock(clock),.sync_reset(sync_reset),.access_bytes(access_mode),.i32(i32),.R32(ER6),.write(write6),.high_access(high_access));
reg32   reg32_7(.clock(clock),.sync_reset(sync_reset),.access_bytes(access_mode),.i32(i32),.R32(ER7),.write(write7),.high_access(high_access));




MPX_8   mpx_8_0(reg_out0_address[2:0],ER0,ER1,ER2,ER3,ER4,ER5,ER6,ER7,Y0);
MPX_8   mpx_8_1(reg_out1_address[2:0],ER0,ER1,ER2,ER3,ER4,ER5,ER6,ER7,Y1);
MPX_8   mpx_8_2(ea_reg_address,ER0,ER1,ER2,ER3,ER4,ER5,ER6,ER7,Y2);


assign reg_out0_address=left_address_sel==`IR1L_SEL ? IR1L :
                                            left_address_sel==`IR1H_SEL? IR1H :
                                            left_address_sel==`IR3H_SEL? IR3H: 07;// SP=07

assign reg_out1_address=right_address_sel==`IR1L_SEL ? IR1L :
                                            right_address_sel==`IR0L_SEL? IR0L :
                                            right_address_sel==2 ? IR3L : 07;//SP=07

assign input_address=write_address_sel==`IR1L_SEL ? IR1L:
                                     write_address_sel==`IR0L_SEL ? IR0L:
                                     write_address_sel==`IR1H_SEL_W ? IR1H:
                                     write_address_sel==2 ? IR3L:
                                     write_address_sel==3 ? IR3H: 07;//SP=07
                                                
assign left_address_out=Y2;
assign reg_left_out=access_mode == `LONG_ACCESS ? Y0 : 
                                  access_mode == `WORD_ACCESS ? (reg_out0_address[3] ==1'b1 ? {16'h0000,Y0[31:16]} : {16'h0000,Y0[15:0]} ) :
                                  reg_out0_address[3] ==1'b0 ? {24'h00_0000,Y0[15:8]} : {24'h00_0000,Y0[7:0]} ;//Note: register field mapping R0H =>0000, R0L=>1000 

assign reg_right_out=access_mode == `LONG_ACCESS ? Y1 : 
                                    access_mode == `WORD_ACCESS ? (reg_out1_address[3] ==1'b1 ? {16'h0000,Y1[31:16]} : {16'h0000,Y1[15:0]} ) :
                                    reg_out1_address[3] ==1'b0 ? {24'h00_0000,Y1[15:8]} : {24'h00_0000,Y1[7:0]} ; //Note: register field mapping R0H =>0000, R0L=>1000 


        assign high_access = !input_address[3];
        assign write0    = reg_write && input_address[2:0]==3'b000;
        assign write1    = reg_write && input_address[2:0]==3'b001;
        assign write2    = reg_write && input_address[2:0]==3'b010;
        assign write3    = reg_write && input_address[2:0]==3'b011;
        assign write4    = reg_write && input_address[2:0]==3'b100;
        assign write5    = reg_write && input_address[2:0]==3'b101;
        assign write6    = reg_write && input_address[2:0]==3'b110;
        assign write7    = reg_write && input_address[2:0]==3'b111;

endmodule

module MPX_8 (address,R0,R1,R2,R3,R4,R5,R6,R7,Y);
        input [2:0] address;
        input  [31:0] R0,R1,R2,R3,R4,R5,R6,R7     ;
        output [31:0] Y;
        wire   [31:0]  R0,R1,R2,R3,R4,R5,R6,R7     ;
        reg    [31:0] Y;
        always @(address or R0 or R1 or R2 or R3 or R4 or R5 or R6 or R7 )
                case(address)
                    3'b000: Y=R0;
                    3'b001: Y=R1;
                    3'b010: Y=R2;
                    3'b011: Y=R3;
                    3'b100: Y=R4;
                    3'b101: Y=R5;
                    3'b110: Y=R6;
                    3'b111: Y=R7;
                endcase
endmodule

module reg32(clock,sync_reset,access_bytes,i32,R32,write,high_access);
        input sync_reset;
        input  clock,high_access;
        input  [1:0]  access_bytes;
        input  [31:0] i32;
        output [31:0] R32;
        reg    [31:0] R32;
        input write;

        always @ (posedge clock) begin
                if (sync_reset) R32 <=32'h0000_0000;
                else if (write && access_bytes==`LONG_ACCESS) R32<=i32;
                else if (write && access_bytes==`WORD_ACCESS && high_access) R32[15:0]  <=i32[15:0];//Note 0000=>R0 1000=>E0
                else if (write && access_bytes==`WORD_ACCESS && !high_access) R32[31:16] <=i32[15:0];
                else if (write && access_bytes==`BYTE_ACCESS && !high_access) R32[7:0]   <=i32[7:0];//Note Reg file Mapping 1000=>R0L
                else if (write && access_bytes==`BYTE_ACCESS &&  high_access) R32[15:8]  <=i32[7:0];//Note 0000=>R0H
              
        end
endmodule