今日は汎用レジスタを作った。
汎用レジスタって何かって言うと、CPUから触れる外部レジスタで汎用に使えるようにしてみたものです。
GEMACがそこそこのボリュームになってきたので、そのテストベンチを書くとなると、外部CPUぐらいの機能があるものが欲しくなってきた。
毎回、CPUの外部バスに接続しているレジスタをスクラッチしているのも面倒なのでそこそこ、汎用性のあるものが欲しくなった。
と、いうことで作ってみた。
大雑把な仕様
バスから書き込みしたらレジスタにデータを保持するバスから読み出しが来たらレジスタのデータを出力する外部入力からビットをリセットできる外部入力からビットをクリアすることができる入力データをそのまま出力する
あと、条件としては
書き込み中の外部入力からのビットセットはバスからの書き込み時もセットされることバスからの書き込み時に外部入力からのビットクリアはしないこと
これくらいの制約でいいだろう。
そしたら、こんなのができた。
module aq_register
parameter BASE_ADDR = 32''h0000_0000
)
(
input RST_N,
input CLK,
input WE,
input [3:0] BE,
input [31:0] ADRS,
input [31:0] WDATA,
output [31:0] RDATA,
input [31:0] DATA0_I,
input [31:0] DATA1_I,
input [31:0] DATA2_I,
input [31:0] DATA3_I,
output [31:0] DATA0_O,
output [31:0] DATA1_O,
output [31:0] DATA2_O,
output [31:0] DATA3_O,
input [31:0] DATA0_S,
input [31:0] DATA1_S,
input [31:0] DATA2_S,
input [31:0] DATA3_S,
input [31:0] DATA0_C,
input [31:0] DATA1_C,
input [31:0] DATA2_C,
input [31:0] DATA3_C
),
// Register 0
reg [31:0] data0_reg;
always @(posedge CLK or negedge RST_N) begin
if(!RST_N) begin
data0_reg[31:0] <= 32''d0;
end else begin
if( (ADRS[31:4] == BASE_ADRS[31:4]) && (ADRS[3:2] == 2''d0)) begin
if(WE) begin
if(BE[0]) data0_reg[ 7: 0] <= WDATA[ 7: 0] | DATA0_S[ 7: 0];
if(BE[1]) data0_reg[15: 0] <= WDATA[15: 8] | DATA0_S[15: 8];
if(BE[2]) data0_reg[23:16] <= WDATA[23:16] | DATA0_S[23:16];
if(BE[3]) data0_reg[31:24] <= WDATA[31:24] | DATA0_S[31:24];
end else begin
data0_reg[31:0] <=
((DATA0_S[31:0] | DATA0_C[31:0]) != 32''d0)?(
(data0_reg[31:0] & ~DATA0_C[31:0]) | DATA0_S[31:0]):
data0_reg[31:0];
end
end
end
end
// Register 1
reg [31:0] data1_reg;
always @(posedge CLK or negedge RST_N) begin
if(!RST_N) begin
data1_reg[31:0] <= 32''d0;
end else begin
if( (ADRS[31:4] == BASE_ADRS[31:4]) && (ADRS[3:2] == 2''d1)) begin
if(WE) begin
if(BE[0]) data1_reg[ 7: 0] <= WDATA[ 7: 0] | DATA1_S[ 7: 0];
if(BE[1]) data1_reg[15: 0] <= WDATA[15: 8] | DATA1_S[15: 8];
if(BE[2]) data1_reg[23:16] <= WDATA[23:16] | DATA1_S[23:16];
if(BE[3]) data1_reg[31:24] <= WDATA[31:24] | DATA1_S[31:24];
end else begin
data1_reg[31:0] <=
((DATA1_S[31:0] | DATA1_C[31:0]) != 32''d0)?(
(data1_reg[31:0] & ~DATA1_C[31:0]) | DATA1_S[31:0]):
data1_reg[31:0];
end
end
end
end
// Register 2
reg [31:0] data2_reg;
always @(posedge CLK or negedge RST_N) begin
if(!RST_N) begin
data2_reg[31:0] <= 32''d0;
end else begin
if( (ADRS[31:4] == BASE_ADRS[31:4]) && (ADRS[3:2] == 2''d2)) begin
if(WE) begin
if(BE[0]) data2_reg[ 7: 0] <= WDATA[ 7: 0] | DATA2_S[ 7: 0];
if(BE[1]) data2_reg[15: 0] <= WDATA[15: 8] | DATA2_S[15: 8];
if(BE[2]) data2_reg[23:16] <= WDATA[23:16] | DATA2_S[23:16];
if(BE[3]) data2_reg[31:24] <= WDATA[31:24] | DATA2_S[31:24];
end else begin
data2_reg[31:0] <=
((DATA2_S[31:0] | DATA2_C[31:0]) != 32''d0)?(
(data2_reg[31:0] & ~DATA2_C[31:0]) | DATA2_S[31:0]):
data2_reg[31:0];
end
end
end
end
// Register 3
reg [31:0] data3_reg;
always @(posedge CLK or negedge RST_N) begin
if(!RST_N) begin
data3_reg[31:0] <= 32''d0;
end else begin
if( (ADRS[31:4] == BASE_ADRS[31:4]) && (ADRS[3:2] == 2''d3)) begin
if(WE) begin
if(BE[0]) data3_reg[ 7: 0] <= WDATA[ 7: 0] | DATA3_S[ 7: 0];
if(BE[1]) data3_reg[15: 0] <= WDATA[15: 8] | DATA3_S[15: 8];
if(BE[2]) data3_reg[23:16] <= WDATA[23:16] | DATA3_S[23:16];
if(BE[3]) data3_reg[31:24] <= WDATA[31:24] | DATA3_S[31:24];
end else begin
data3_reg[31:0] <=
((DATA3_S[31:0] | DATA3_C[31:0]) != 32''d0)?(
(data3_reg[31:0] & ~DATA3_C[31:0]) | DATA3_S[31:0]):
data3_reg[31:0];
end
end
end
end
assign RDATA[31:0] = ((ADRS[31:4] == BASE_ADRS[31:4]) && (ADRS[3:2] == 2''d0))?(data0_reg[31:0] | DATA0_I[31:0]):32''d0) |
((ADRS[31:4] == BASE_ADRS[31:4]) && (ADRS[3:2] == 2''d1))?(data1_reg[31:0] | DATA1_I[31:0]):32''d0) |
((ADRS[31:4] == BASE_ADRS[31:4]) && (ADRS[3:2] == 2''d2))?(data2_reg[31:0] | DATA2_I[31:0]):32''d0) |
((ADRS[31:4] == BASE_ADRS[31:4]) && (ADRS[3:2] == 2''d3))?(data3_reg[31:0] | DATA3_I[31:0]):32''d0),
assign DATA0_O[31:0] = data0_reg[31:0];
assign DATA1_O[31:0] = data1_reg[31:0];
assign DATA2_O[31:0] = data2_reg[31:0];
assign DATA3_O[31:0] = data3_reg[31:0];
end module;
まだ、シミュレーションしてないので、仕様を満足してるかどうかわからんが・・・