From 847eae23ab430c3669e0088a774ba8e3ce8f376b Mon Sep 17 00:00:00 2001 From: Andreas Olofsson Date: Thu, 12 Nov 2015 10:49:40 -0500 Subject: [PATCH] Adding proper read alignment for ememory model -Byte/shorts now work --- emesh/dv/ememory.v | 36 ++++++------ emesh/hdl/emesh_rdalign.v | 118 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+), 16 deletions(-) create mode 100644 emesh/hdl/emesh_rdalign.v diff --git a/emesh/dv/ememory.v b/emesh/dv/ememory.v index d8f30df..e2f77bd 100644 --- a/emesh/dv/ememory.v +++ b/emesh/dv/ememory.v @@ -44,7 +44,7 @@ module ememory(/*AUTOARG*/ wire [AW-1:0] srcaddr_out; wire [AW-1:0] data_out; - reg hilo_sel; + reg [2:0] align_addr; wire write_in; wire [1:0] datamode_in; @@ -52,8 +52,8 @@ module ememory(/*AUTOARG*/ wire [AW-1:0] dstaddr_in; wire [DW-1:0] data_in; wire [AW-1:0] srcaddr_in; - wire [DW-1:0] data_align; - + wire [DW-1:0] din_aligned; + wire [DW-1:0] dout_aligned; packet2emesh #(.PW(PW)) p2e ( @@ -79,13 +79,13 @@ module ememory(/*AUTOARG*/ assign addr[MAW-1:0] = dstaddr_in[MAW+2:3]; //Shift up - assign data_align[DW-1:0] = (datamode_in[1:0]==2'b00) ? {(4){data_in[7:0]}} : + assign din_aligned[DW-1:0] = (datamode_in[1:0]==2'b00) ? {(4){data_in[7:0]}} : (datamode_in[1:0]==2'b01) ? {(2){data_in[15:0]}} : data_in[31:0]; //Data-in (hardoded width) - assign din[63:0] =(datamode_in[1:0]==2'b11) ? {srcaddr_in[31:0],data_align[31:0]}: - {data_align[31:0],data_align[31:0]}; + assign din[63:0] =(datamode_in[1:0]==2'b11) ? {srcaddr_in[31:0],din_aligned[31:0]}: + {din_aligned[31:0],din_aligned[31:0]}; //Write mask always@* casez({write_in, datamode_in[1:0],dstaddr_in[2:0]}) @@ -136,19 +136,23 @@ module ememory(/*AUTOARG*/ if(mem_rd & ~wait_in) begin write_out <= 1'b1; - hilo_sel <= dstaddr_in[2]; + align_addr[2:0] <= dstaddr_in[2:0]; datamode_out[1:0] <= datamode_in[1:0]; ctrlmode_out[4:0] <= ctrlmode_in[3:0]; dstaddr_out[AW-1:0] <= srcaddr_in[AW-1:0]; end - - assign srcaddr_out[AW-1:0] = dout[63:32]; + //Data alignment for readback + emesh_rdalign emesh_rdalign (// Outputs + .data_out (dout_aligned[DW-1:0]), + // Inputs + .datamode (datamode_out[1:0]), + .addr (align_addr[2:0]), + .data_in (dout[2*DW-1:0])); - //note sure about this??? - assign data_out[DW-1:0] = hilo_sel ? dout[63:32] : - dout[31:0]; + assign srcaddr_out[AW-1:0] = dout_aligned[63:32]; + assign data_out[DW-1:0] = dout_aligned[31:0]; //Concatenate emesh2packet #(.PW(PW)) @@ -172,13 +176,13 @@ module ememory(/*AUTOARG*/ .wait_in (1'b0), /*AUTOINST*/ // Inputs - .clk (clk), - .nreset (nreset), - .coreid (coreid[IDW-1:0])); + .clk (clk), + .nreset (nreset), + .coreid (coreid[IDW-1:0])); endmodule // emesh_memory // Local Variables: -// verilog-library-directories:("." "../dv" ) +// verilog-library-directories:("." "../hdl" ) // End: diff --git a/emesh/hdl/emesh_rdalign.v b/emesh/hdl/emesh_rdalign.v new file mode 100644 index 0000000..d6b2125 --- /dev/null +++ b/emesh/hdl/emesh_rdalign.v @@ -0,0 +1,118 @@ +/*The Epiphany memory model assumes the following alignment on incoming transactions*/ + +//Byte Mode: +//ADDR[2:0] B7 B6 B5 B4 B3 B2 B1 B0 +//x00 0 0 0 MB0 0 0 0 MB0 +//x01 0 0 0 MB1 0 0 0 MB1 +//x10 0 0 0 MB2 0 0 0 MB2 +//x11 0 0 0 MB3 0 0 0 MB3 + +//Short Mode: +//ADDR[2:0] B7 B6 B5 B4 B3 B2 B1 B0 +//x00 0 0 MB1 MB0 0 0 MB1 MB0 +//x10 0 0 MB3 MB2 0 0 MB3 MB2 + +//Word Mode: +//ADDR[2:0] B7 B6 B5 B4 B3 B2 B1 B0 +//x00 MB3 MB2 MB1 MB0 MB3 MB2 MB1 MB0 + +//Double Mode: +//ADDR[2:0] B7 B6 B5 B4 B3 B2 B1 B0 +//000 MB7 MB6 MB5 MB4 MB3 MB2 MB1 MB0 + +module emesh_rdalign (/*AUTOARG*/ + // Outputs + data_out, + // Inputs + datamode, addr, data_in + ); + + parameter DW = 32; + + //Inputs + input [1:0] datamode; + input [2:0] addr; + input [2*DW-1:0] data_in; + + //Outputs + output [DW-1:0] data_out; + + + //wires + wire [DW-1:0] data_low; + + + //wires + /* verilator lint_off UNOPTFLAT */ + wire [3:0] byte0_sel; + /* verilator lint_on UNOPTFLAT */ + wire [3:0] byte1_sel; + wire [3:0] byte2_sel; + wire [3:0] byte3_sel; + wire [31:0] data_mux; + wire [31:0] data_aligned; + + assign data_mux[31:0] = ((addr[2] & (datamode[1:0]!=2'b11))) ? data_in[2*DW-1:DW] : data_in[DW-1:0]; + + + //Byte0 + assign byte0_sel[3] = datamode[1:0]==2'b00 & addr[1:0]==2'b11; + + assign byte0_sel[2] = datamode[1:0]==2'b00 & addr[1:0]==2'b10 | + datamode[1:0]==2'b01 & addr[1:0]==2'b10; + + assign byte0_sel[1] = datamode[1:0]==2'b00 & addr[1:0]==2'b01; + + assign byte0_sel[0] = ~(|byte0_sel[3:1]); + + + //Byte1 + assign byte1_sel[1] = (datamode[1:0]==2'b01 & addr[1:0]==2'b00) | + datamode[1:0]==2'b10 | + datamode[1:0]==2'b11; + + assign byte1_sel[3] = datamode[1:0]==2'b01 & addr[1:0]==2'b10; + + assign byte1_sel[2] = 1'b0; + assign byte1_sel[0] = 1'b0; + + + //Byte2 + assign byte2_sel[2] = datamode[1:0]==2'b10 | + datamode[1:0]==2'b11; + + assign byte2_sel[3] = 1'b0; + assign byte2_sel[1] = 1'b0; + assign byte2_sel[0] = 1'b0; + + //Byte3 + assign byte3_sel[3] = datamode[1:0]==2'b10 | + datamode[1:0]==2'b11; + + assign byte3_sel[2] = 1'b0; + assign byte3_sel[1] = 1'b0; + assign byte3_sel[0] = 1'b0; + + //Alignment for lower 32 bits(upper 32 bits don't need alignment) + + //B0: 32 NANDs,8 NORS + assign data_aligned[7:0] = {(8){byte0_sel[3]}} & data_mux[31:24] | + {(8){byte0_sel[2]}} & data_mux[23:16] | + {(8){byte0_sel[1]}} & data_mux[15:8] | + {(8){byte0_sel[0]}} & data_mux[7:0]; + //B1: + assign data_aligned[15:8] = {(8){byte1_sel[3]}} & data_mux[31:24] | + {(8){byte1_sel[1]}} & data_mux[15:8]; + + //B2: 8 NANDS + assign data_aligned[23:16] = {(8){byte2_sel[2]}} & data_mux[23:16]; + + //B3: + assign data_aligned[31:24] = {(8){byte3_sel[3]}} & data_mux[31:24]; + + assign data_out[DW-1:0] = data_aligned[DW-1:0]; + +endmodule // emesh_rdalign + + +