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
|