4.RAM Module
RAMサイズは、16KBです。いつものベンチマークプログラムをコンパイルしたらちょっとダイエットしただけで収まりました。ベンチマークは8ビットアクセスが主体ですから、MIPS(32KB)よりもコード効率がいいのでしょう。
あとで、サイズ変更が容易なようにAddress関係は、parameterでビット幅を指定しておきます。
BYTE単位でのW/Rアクセスがあるので、8ビット幅、2024WORDSのRAMを8個WIZARDで作成します。WIZARDでは、2ポートを選択しSTRATIXUで作成します。なお、RAMにプログラムを読み込ませる必要がありますので、初期化ファイルを用意します。Alteraの場合、INTEL HEXフォーマットで読ませます。
ところで、H8のアセンブラ(秋月)は、モトローラのSフォーマットという形式で出力されます。(初期デバッグでは、アセンブラでテストプログラムを書きます。)そこで、SフォーマットからINTEL
HEX形式に出力するコンバータツールを作成しました。8個のRAM用にcode0.hex、code1.hex、、、、code7.hexを出力します。Wizardでは、これらの初期化ファイルを指定します。
RAM ポートは、二つあり、
ポートaのWriteポートは使用しません。
なお、RAM内のAR レジスタ等は、参照することが出来ないのでRAMの外で同じ物を作ってやります。
`include "define.h" //Jun.4.2004 AW 9=>11 module h8_ram_module(clock,sync_reset,ram_write,paddress_sel,EA,data_address_latch,bcc_ea_sel,IR,MOUT,access_mode,ALU_OUT,ram_data_in_sel,pc_reg,next_pc_offset,ea_left_sel,CCR,bus_state); parameter AW=11; input clock; input [1:0] paddress_sel; input [31:0] ALU_OUT; input [23:0] EA; output [63:0] IR; output [31:0] MOUT; output [23:0] pc_reg; input ram_write; input [1:0] access_mode; input bcc_ea_sel; input sync_reset; input data_address_latch; input ram_data_in_sel; input [2:0] next_pc_offset; input [3:0] ea_left_sel; input [7:0] CCR; input [1:0] bus_state; wire [7:0] qa0,qa1,qa2,qa3,qa4,qa5,qa6,qa7; wire [7:0] qb0,qb1,qb2,qb3,qb4,qb5,qb6,qb7; reg [7:0] in_data0,in_data1,in_data2,in_data3,in_data4,in_data5,in_data6,in_data7; reg [AW-1:0] paddress0,paddress1,paddress2,paddress3,paddress4,paddress5,paddress6,paddress7; reg [AW-1:0] daddress0,daddress1,daddress2,daddress3,daddress4,daddress5,daddress6,daddress7; reg [63:0] IR; reg [31:0] MOUT; reg write0,write1,write2,write3,write4,write5,write6,write7; reg [23:0] ea_reg,ea_reg2;//Register reg [23:0] pc_reg;//Register reg [1:0] access_mode_reg;//Register wire [23:0] DAddr,PAddr,NEXT_PC; wire [31:0] in_data; //Registers always @(posedge clock) begin if (sync_reset) ea_reg <=0; else ea_reg<=EA; end always @(posedge clock) begin if (sync_reset) ea_reg2 <=0; else ea_reg2<=ea_reg; end always @(posedge clock) begin if (sync_reset) pc_reg <=0; else begin pc_reg <=PAddr; end end always @(posedge clock) begin if (sync_reset) access_mode_reg <=0; else begin access_mode_reg <=access_mode; end end assign NEXT_PC=pc_reg+{next_pc_offset,1'b0}; assign DAddr=data_address_latch ? ALU_OUT[23:0] :EA;//May.31.2004 ; assign PAddr=paddress_sel==`NEXT_PC_SEL ? NEXT_PC : paddress_sel==`EA_SEL ? EA : paddress_sel==`MOUT_SEL ? MOUT[23:0] : bcc_ea_sel ? EA : NEXT_PC; assign in_data=ram_data_in_sel==`ALU_OUT_SEL ? ALU_OUT : bus_state==`INT_STATE ? {CCR,pc_reg} : {8'h00,NEXT_PC};//May.31.2004 //paddressx, daddressx ,IR,MOUT,writex,in_datax は組み合わせ回路 always @(PAddr) begin paddress0=PAddr[AW-1+3:3]; paddress1=PAddr[AW-1+3:3]; paddress2=PAddr[AW-1+3:3]; paddress3=PAddr[AW-1+3:3]; paddress4=PAddr[AW-1+3:3]; paddress5=PAddr[AW-1+3:3]; paddress6=PAddr[AW-1+3:3]; paddress7=PAddr[AW-1+3:3]; if(PAddr[2:0]==2) begin paddress0=paddress0+1; paddress1=paddress0; end else if(PAddr[2:0]==4) begin paddress0=paddress0+1; paddress1=paddress0; paddress2=paddress0; paddress3=paddress0; end else if(PAddr[2:0]==6) begin paddress0=paddress0+1; paddress1=paddress0; paddress2=paddress0; paddress3=paddress0; paddress4=paddress0; paddress5=paddress0; end end always @(pc_reg,qa0,qa1,qa2,qa3,qa4,qa5,qa6,qa7 ) begin IR={qa0,qa1,qa2,qa3,qa4,qa5,qa6,qa7}; if(pc_reg[2:0]==2) begin // paddress0=paddress0+1; // paddress1=paddress0; IR={qa2,qa3,qa4,qa5,qa6,qa7,qa0,qa1}; end else if(pc_reg[2:0]==4) begin // paddress0=paddress0+1; // paddress1=paddress0; // paddress2=paddress0; // paddress3=paddress0; IR={qa4,qa5,qa6,qa7,qa0,qa1,qa2,qa3}; end else if(pc_reg[2:0]==6) begin // paddress0=paddress0+1; // paddress1=paddress0; // paddress2=paddress0; // paddress3=paddress0; // paddress4=paddress0; // paddress5=paddress0; IR={qa6,qa7,qa0,qa1,qa2,qa3,qa4,qa5}; end end //Data port always @(DAddr,access_mode,in_data,ram_write ) begin daddress0=DAddr[AW-1+3:3]; daddress1=DAddr[AW-1+3:3]; daddress2=DAddr[AW-1+3:3]; daddress3=DAddr[AW-1+3:3]; daddress4=DAddr[AW-1+3:3]; daddress5=DAddr[AW-1+3:3]; daddress6=DAddr[AW-1+3:3]; daddress7=DAddr[AW-1+3:3]; write0=0; in_data0=8'hxx; write1=0; in_data1=8'hxx; write2=0; in_data2=8'hxx; write3=0; in_data3=8'hxx; write4=0; in_data4=8'hxx; write5=0; in_data5=8'hxx; write6=0; in_data6=8'hxx; write7=0; in_data7=8'hxx; if(DAddr[2:0]==0) begin if (access_mode==`BYTE_ACCESS) begin // MOUT={24'h00_0000,qb0}; write0=ram_write; in_data0=in_data[7:0]; end else if ( access_mode==`WORD_ACCESS) begin // MOUT={16'h0000,qb0,qb1}; write0=ram_write; write1=ram_write; in_data0=in_data[15:8]; in_data1=in_data[7:0]; end else begin // MOUT={qb0,qb1,qb2,qb3}; write0=ram_write; write1=ram_write; write2=ram_write; write3=ram_write; in_data0=in_data[31:24]; in_data1=in_data[23:16]; in_data2=in_data[15:8]; in_data3=in_data[7:0]; end end else if(DAddr[2:0]==1) begin daddress0=daddress0+1; // if (access_mode==`BYTE_ACCESS) begin //BYTE ACCESS しかない // MOUT={24'h00_0000,qb1}; write1=ram_write; in_data1=in_data[7:0]; // end end else if(DAddr[2:0]==2) begin daddress0=daddress0+1; daddress1=daddress0; if (access_mode==`BYTE_ACCESS) begin // MOUT={24'h00_0000,qb2}; write2=ram_write; in_data2=in_data[7:0]; end else if ( access_mode==`WORD_ACCESS) begin // MOUT={16'h0000,qb2,qb3}; write2=ram_write; write3=ram_write; in_data2=in_data[15:8]; in_data3=in_data[7:0]; end else begin // MOUT={qb2,qb3,qb4,qb5}; write2=ram_write; write3=ram_write; write4=ram_write; write5=ram_write; in_data2=in_data[31:24]; in_data3=in_data[23:16]; in_data4=in_data[15:8]; in_data5=in_data[7:0]; end end else if(DAddr[2:0]==3) begin daddress0=daddress0+1; daddress1=daddress0; daddress2=daddress0; // if (access_mode==`BYTE_ACCESS) begin //BYTE ACCESS しかない // MOUT={24'h00_0000,qb3}; write3=ram_write; in_data3=in_data[7:0]; // end end else if(DAddr[2:0]==4) begin daddress0=daddress0+1; daddress1=daddress0; daddress2=daddress0; daddress3=daddress0; if (access_mode==`BYTE_ACCESS) begin // MOUT={24'h00_0000,qb4}; write4=ram_write; in_data4=in_data[7:0]; end else if ( access_mode==`WORD_ACCESS) begin // MOUT={16'h0000,qb4,qb5}; write4=ram_write; write5=ram_write; in_data4=in_data[15:8]; in_data5=in_data[7:0]; end else begin // MOUT={qb4,qb5,qb6,qb7}; write4=ram_write; write5=ram_write; write6=ram_write; write7=ram_write; in_data4=in_data[31:24]; in_data5=in_data[23:16]; in_data6=in_data[15:8]; in_data7=in_data[7:0]; end end else if(DAddr[2:0]==5) begin daddress0=daddress0+1; daddress1=daddress0; daddress2=daddress0; daddress3=daddress0; daddress4=daddress0; // if (access_mode==`BYTE_ACCESS) begin //BYTE ACCESS しかない // MOUT={24'h00_0000,qb5}; write5=ram_write; in_data5=in_data[7:0]; // end else if ( access_mode==`WORD_ACCESS) begin end else if(DAddr[2:0]==6) begin daddress0=daddress0+1; daddress1=daddress0; daddress2=daddress0; daddress3=daddress0; daddress4=daddress0; daddress5=daddress0; if (access_mode==`BYTE_ACCESS) begin // MOUT={24'h00_0000,qb6}; write6=ram_write; in_data6=in_data[7:0]; end else if ( access_mode==`WORD_ACCESS) begin // MOUT={16'h0000,qb6,qb7}; write6=ram_write; write7=ram_write; in_data6=in_data[15:8]; in_data7=in_data[7:0]; end else begin // MOUT={qb6,qb7,qb0,qb1}; write6=ram_write; write7=ram_write; write0=ram_write; write1=ram_write; in_data6=in_data[31:24]; in_data7=in_data[23:16]; in_data0=in_data[15:8]; in_data1=in_data[7:0]; end end else if(DAddr[2:0]==7) begin daddress0=daddress0+1; daddress1=daddress0; daddress2=daddress0; daddress3=daddress0; daddress4=daddress0; daddress5=daddress0; daddress6=daddress0; // if (access_mode==`BYTE_ACCESS) begin //BYTE ACCESS しかない // MOUT={24'h00_0000,qb7}; write7=ram_write; in_data7=in_data[7:0]; // end else if ( access_mode==`WORD_ACCESS) begin end end //Data Out Port always @(ea_reg,qb0,qb1,qb2,qb3,qb4,qb5,qb6,qb7,access_mode,ea_reg2) begin if (access_mode==`BYTE_ACCESS) begin MOUT={24'h00_0000,qb0}; end else if ( access_mode==`WORD_ACCESS) begin MOUT={16'h0000,qb0,qb1}; end else begin MOUT={qb0,qb1,qb2,qb3}; end if(ea_reg2[2:0]==1) begin // if (access_mode==`BYTE_ACCESS) begin //BYTE ACCESS しかない MOUT={24'h00_0000,qb1}; // end end else if(ea_reg2[2:0]==2) begin if (access_mode==`BYTE_ACCESS) begin MOUT={24'h00_0000,qb2}; end else if ( access_mode==`WORD_ACCESS) begin MOUT={16'h0000,qb2,qb3}; end else begin MOUT={qb2,qb3,qb4,qb5}; end end else if(ea_reg2[2:0]==3) begin // if (access_mode==`BYTE_ACCESS) begin //BYTE ACCESS しかない MOUT={24'h00_0000,qb3}; // end end else if(ea_reg2[2:0]==4) begin if (access_mode==`BYTE_ACCESS) begin MOUT={24'h00_0000,qb4}; end else if ( access_mode==`WORD_ACCESS) begin MOUT={16'h0000,qb4,qb5}; end else begin MOUT={qb4,qb5,qb6,qb7}; end end else if(ea_reg2[2:0]==5) begin // if (access_mode==`BYTE_ACCESS) begin //BYTE ACCESS しかない MOUT={24'h00_0000,qb5}; // end else if ( access_mode==`WORD_ACCESS) begin end else if(ea_reg2[2:0]==6) begin if (access_mode==`BYTE_ACCESS) begin MOUT={24'h00_0000,qb6}; end else if (access_mode==`WORD_ACCESS) begin MOUT={16'h0000,qb6,qb7}; end else begin MOUT={qb6,qb7,qb0,qb1}; end end else if(ea_reg2[2:0]==7) begin // if (access_mode==`BYTE_ACCESS) begin //BYTE ACCESS しかない MOUT={24'h00_0000,qb7}; // end else if ( access_mode==`WORD_ACCESS) begin end end ram512x8_0 u0(.data_a(8'h00),.data_b(in_data0),.address_a(paddress0),.address_b(daddress0), .wren_a(1'b0),.wren_b(write0),.clock(clock),.q_a(qa0),.q_b(qb0)); ram512x8_1 u1(.data_a(8'h00),.data_b(in_data1),.address_a(paddress1),.address_b(daddress1), .wren_a(1'b0),.wren_b(write1),.clock(clock),.q_a(qa1),.q_b(qb1)); ram512x8_2 u2(.data_a(8'h00),.data_b(in_data2),.address_a(paddress2),.address_b(daddress2), .wren_a(1'b0),.wren_b(write2),.clock(clock),.q_a(qa2),.q_b(qb2)); ram512x8_3 u3(.data_a(8'h00),.data_b(in_data3),.address_a(paddress3),.address_b(daddress3), .wren_a(1'b0),.wren_b(write3),.clock(clock),.q_a(qa3),.q_b(qb3)); ram512x8_4 u4(.data_a(8'h00),.data_b(in_data4),.address_a(paddress4),.address_b(daddress4), .wren_a(1'b0),.wren_b(write4),.clock(clock),.q_a(qa4),.q_b(qb4)); ram512x8_5 u5(.data_a(8'h00),.data_b(in_data5),.address_a(paddress5),.address_b(daddress5), .wren_a(1'b0),.wren_b(write5),.clock(clock),.q_a(qa5),.q_b(qb5)); ram512x8_6 u6(.data_a(8'h00),.data_b(in_data6),.address_a(paddress6),.address_b(daddress6), .wren_a(1'b0),.wren_b(write6),.clock(clock),.q_a(qa6),.q_b(qb6)); ram512x8_7 u7(.data_a(8'h00),.data_b(in_data7),.address_a(paddress7),.address_b(daddress7), .wren_a(1'b0),.wren_b(write7),.clock(clock),.q_a(qa7),.q_b(qb7)); endmodule |