Skip to content

Commit

Permalink
FML: early ack
Browse files Browse the repository at this point in the history
  • Loading branch information
Sebastien Bourdeauducq committed Jul 13, 2011
1 parent 7dda0b9 commit 8cfa0da
Show file tree
Hide file tree
Showing 9 changed files with 222 additions and 234 deletions.
6 changes: 3 additions & 3 deletions boards/milkymist-one/rtl/ddram.v
@@ -1,6 +1,6 @@
/*
* Milkymist SoC
* Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq
* Copyright (C) 2007, 2008, 2009, 2010, 2011 Sebastien Bourdeauducq
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -34,7 +34,7 @@ module ddram #(
input [`SDRAM_DEPTH-1:0] fml_adr,
input fml_stb,
input fml_we,
output fml_ack,
output fml_eack,
input [7:0] fml_sel,
input [63:0] fml_di,
output [63:0] fml_do,
Expand Down Expand Up @@ -101,7 +101,7 @@ hpdmc #(
.fml_adr(fml_adr),
.fml_stb(fml_stb),
.fml_we(fml_we),
.fml_ack(fml_ack),
.fml_eack(fml_eack),
.fml_sel(fml_sel),
.fml_di(fml_di),
.fml_do(fml_do),
Expand Down
8 changes: 4 additions & 4 deletions boards/milkymist-one/rtl/system.v
Expand Up @@ -562,7 +562,7 @@ wire [63:0] fml_brg_dr,
wire [`SDRAM_DEPTH-1:0] fml_adr;
wire fml_stb;
wire fml_we;
wire fml_ack;
wire fml_eack;
wire [7:0] fml_sel;
wire [63:0] fml_dw;
wire [63:0] fml_dr;
Expand Down Expand Up @@ -634,7 +634,7 @@ fmlarb #(
.s_adr(fml_adr),
.s_stb(fml_stb),
.s_we(fml_we),
.s_ack(fml_ack),
.s_eack(fml_eack),
.s_sel(fml_sel),
.s_di(fml_dr),
.s_do(fml_dw)
Expand Down Expand Up @@ -942,7 +942,7 @@ ddram #(
.fml_adr(fml_adr),
.fml_stb(fml_stb),
.fml_we(fml_we),
.fml_ack(fml_ack),
.fml_eack(fml_eack),
.fml_sel(fml_sel),
.fml_di(fml_dw),
.fml_do(fml_dr),
Expand Down Expand Up @@ -1312,7 +1312,7 @@ fmlmeter #(
.csr_do(csr_dr_fmlmeter),

.fml_stb(fml_stb),
.fml_ack(fml_ack),
.fml_ack(fml_eack),
.fml_we(fml_we),
.fml_adr(fml_adr)
);
Expand Down
149 changes: 79 additions & 70 deletions cores/fmlarb/rtl/fmlarb.v
@@ -1,6 +1,6 @@
/*
* Milkymist SoC
* Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq
* Copyright (C) 2007, 2008, 2009, 2010, 2011 Sebastien Bourdeauducq
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -73,7 +73,7 @@ module fmlarb #(
output reg [fml_depth-1:0] s_adr,
output reg s_stb,
output reg s_we,
input s_ack,
input s_eack,
output reg [7:0] s_sel,
input [63:0] s_di,
output reg [63:0] s_do
Expand All @@ -86,6 +86,13 @@ assign m3_do = s_di;
assign m4_do = s_di;
assign m5_do = s_di;

wire m0_stbm;
wire m1_stbm;
wire m2_stbm;
wire m3_stbm;
wire m4_stbm;
wire m5_stbm;

reg [2:0] master;
reg [2:0] next_master;

Expand All @@ -102,114 +109,116 @@ always @(*) begin
next_master = master;

case(master)
3'd0: if(~m0_stb | s_ack) begin
if(m1_stb) next_master = 3'd1;
else if(m2_stb) next_master = 3'd2;
else if(m3_stb) next_master = 3'd3;
else if(m4_stb) next_master = 3'd4;
else if(m5_stb) next_master = 3'd5;
end
3'd1: if(~m1_stb | s_ack) begin
if(m0_stb) next_master = 3'd0;
else if(m3_stb) next_master = 3'd3;
else if(m4_stb) next_master = 3'd4;
else if(m5_stb) next_master = 3'd5;
else if(m2_stb) next_master = 3'd2;
end
3'd2: if(~m2_stb | s_ack) begin
if(m0_stb) next_master = 3'd0;
else if(m3_stb) next_master = 3'd3;
else if(m4_stb) next_master = 3'd4;
else if(m5_stb) next_master = 3'd5;
else if(m1_stb) next_master = 3'd1;
end
3'd3: if(~m3_stb | s_ack) begin
if(m0_stb) next_master = 3'd0;
else if(m4_stb) next_master = 3'd4;
else if(m5_stb) next_master = 3'd5;
else if(m1_stb) next_master = 3'd1;
else if(m2_stb) next_master = 3'd2;
end
3'd4: if(~m4_stb | s_ack) begin
if(m0_stb) next_master = 3'd0;
else if(m5_stb) next_master = 3'd5;
else if(m1_stb) next_master = 3'd1;
else if(m2_stb) next_master = 3'd2;
else if(m3_stb) next_master = 3'd3;
end
default: if(~m5_stb | s_ack) begin // 3'd5
if(m0_stb) next_master = 3'd0;
else if(m1_stb) next_master = 3'd1;
else if(m2_stb) next_master = 3'd2;
else if(m3_stb) next_master = 3'd3;
else if(m4_stb) next_master = 3'd4;
3'd0: if(~m0_stbm | s_eack) begin
if(m1_stbm) next_master = 3'd1;
else if(m2_stbm) next_master = 3'd2;
else if(m3_stbm) next_master = 3'd3;
else if(m4_stbm) next_master = 3'd4;
else if(m5_stbm) next_master = 3'd5;
end
3'd1: if(~m1_stbm | s_eack) begin
if(m0_stbm) next_master = 3'd0;
else if(m3_stbm) next_master = 3'd3;
else if(m4_stbm) next_master = 3'd4;
else if(m5_stbm) next_master = 3'd5;
else if(m2_stbm) next_master = 3'd2;
end
3'd2: if(~m2_stbm | s_eack) begin
if(m0_stbm) next_master = 3'd0;
else if(m3_stbm) next_master = 3'd3;
else if(m4_stbm) next_master = 3'd4;
else if(m5_stbm) next_master = 3'd5;
else if(m1_stbm) next_master = 3'd1;
end
3'd3: if(~m3_stbm | s_eack) begin
if(m0_stbm) next_master = 3'd0;
else if(m4_stbm) next_master = 3'd4;
else if(m5_stbm) next_master = 3'd5;
else if(m1_stbm) next_master = 3'd1;
else if(m2_stbm) next_master = 3'd2;
end
3'd4: if(~m4_stbm | s_eack) begin
if(m0_stbm) next_master = 3'd0;
else if(m5_stbm) next_master = 3'd5;
else if(m1_stbm) next_master = 3'd1;
else if(m2_stbm) next_master = 3'd2;
else if(m3_stbm) next_master = 3'd3;
end
default: if(~m5_stbm | s_eack) begin // 3'd5
if(m0_stbm) next_master = 3'd0;
else if(m1_stbm) next_master = 3'd1;
else if(m2_stbm) next_master = 3'd2;
else if(m3_stbm) next_master = 3'd3;
else if(m4_stbm) next_master = 3'd4;
end
endcase
end

/* Generate ack signals */
assign m0_ack = (master == 3'd0) & s_ack;
assign m1_ack = (master == 3'd1) & s_ack;
assign m2_ack = (master == 3'd2) & s_ack;
assign m3_ack = (master == 3'd3) & s_ack;
assign m4_ack = (master == 3'd4) & s_ack;
assign m5_ack = (master == 3'd5) & s_ack;

/* Mux control signals */
always @(*) begin
case(master)
3'd0: begin
s_adr = m0_adr;
s_stb = m0_stb;
s_stb = m0_stbm;
s_we = m0_we;
end
3'd1: begin
s_adr = m1_adr;
s_stb = m1_stb;
s_stb = m1_stbm;
s_we = m1_we;
end
3'd2: begin
s_adr = m2_adr;
s_stb = m2_stb;
s_stb = m2_stbm;
s_we = m2_we;
end
3'd3: begin
s_adr = m3_adr;
s_stb = m3_stb;
s_stb = m3_stbm;
s_we = m3_we;
end
3'd4: begin
s_adr = m4_adr;
s_stb = m4_stb;
s_stb = m4_stbm;
s_we = m4_we;
end
default: begin // 3'd5
s_adr = m5_adr;
s_stb = m5_stb;
s_stb = m5_stbm;
s_we = m5_we;
end
endcase
end

/* Mux data write signals */

wire write_burst_start = s_we & s_ack;
/* Generate delayed ack signals and masked strobes */
fmlarb_dack dack0(.sys_clk(sys_clk), .sys_rst(sys_rst),
.stb(m0_stb), .eack((master == 3'd0) & s_eack), .we(m0_we),
.stbm(m0_stbm), .ack(m0_ack));
fmlarb_dack dack1(.sys_clk(sys_clk), .sys_rst(sys_rst),
.stb(m1_stb), .eack((master == 3'd1) & s_eack), .we(m1_we),
.stbm(m1_stbm), .ack(m1_ack));
fmlarb_dack dack2(.sys_clk(sys_clk), .sys_rst(sys_rst),
.stb(m2_stb), .eack((master == 3'd2) & s_eack), .we(m2_we),
.stbm(m2_stbm), .ack(m2_ack));
fmlarb_dack dack3(.sys_clk(sys_clk), .sys_rst(sys_rst),
.stb(m3_stb), .eack((master == 3'd3) & s_eack), .we(m3_we),
.stbm(m3_stbm), .ack(m3_ack));
fmlarb_dack dack4(.sys_clk(sys_clk), .sys_rst(sys_rst),
.stb(m4_stb), .eack((master == 3'd4) & s_eack), .we(m4_we),
.stbm(m4_stbm), .ack(m4_ack));
fmlarb_dack dack5(.sys_clk(sys_clk), .sys_rst(sys_rst),
.stb(m5_stb), .eack((master == 3'd5) & s_eack), .we(m5_we),
.stbm(m5_stbm), .ack(m5_ack));

/* Mux data write signals */
reg [2:0] wmaster;
reg [1:0] burst_counter;

always @(posedge sys_clk) begin
if(sys_rst) begin
if(sys_rst)
wmaster <= 3'd0;
burst_counter <= 2'd0;
end else begin
if(|burst_counter)
burst_counter <= burst_counter - 2'd1;
if(write_burst_start)
burst_counter <= 2'd2;
if(~write_burst_start & ~(|burst_counter))
wmaster <= next_master;
end
else if(s_we & s_eack)
wmaster <= master;
end

always @(*) begin
Expand Down
82 changes: 82 additions & 0 deletions cores/fmlarb/rtl/fmlarb_dack.v
@@ -0,0 +1,82 @@
/*
* Milkymist SoC
* Copyright (C) 2007, 2008, 2009, 2010, 2011 Sebastien Bourdeauducq
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

/*
* Generate ack signal from early ack signal and mask strobe.
* After an early acked write, it should pulse after 2 cycles.
* After an early acked read, it should pulse after CL+3 cycles, that is
* 5 cycles when tim_cas = 0 (assumed here)
* 6 cycles when tim_cas = 1
*/

module fmlarb_dack(
input sys_clk,
input sys_rst,

input stb,
input eack,
input we,

output stbm,
output reg ack
);

wire read = eack & ~we;
wire write = eack & we;

reg ack_read2;
reg ack_read1;
reg ack_read0;

always @(posedge sys_clk) begin
if(sys_rst) begin
ack_read2 <= 1'b0;
ack_read1 <= 1'b0;
ack_read0 <= 1'b0;
end else begin
ack_read2 <= read;
ack_read1 <= ack_read2;
ack_read0 <= ack_read1;
end
end

reg ack0;
always @(posedge sys_clk) begin
if(sys_rst) begin
ack0 <= 1'b0;
ack <= 1'b0;
end else begin
ack0 <= ack_read0|write;
ack <= ack0;
end
end

reg mask;
assign stbm = stb & ~mask;

always @(posedge sys_clk) begin
if(sys_rst)
mask <= 1'b0;
else begin
if(eack)
mask <= 1'b1;
if(ack)
mask <= 1'b0;
end
end

endmodule

0 comments on commit 8cfa0da

Please sign in to comment.