1
0
mirror of https://github.com/aolofsson/oh.git synced 2025-01-30 02:32:53 +08:00

Renaming enoc to emesh for consistency

This commit is contained in:
aolofsson 2022-06-18 08:51:24 -04:00
parent f938b7acac
commit 60fdcbd3e6
24 changed files with 347 additions and 386 deletions

View File

@ -1,12 +1,12 @@
/*******************************************************************************
* Function: ENOC Command Decoder
* Author: Andreas Olofsson
* Function: EMESH Command Decoder
* Author: Andreas Olofsson
* License: MIT (see LICENSE file in OH! repository)
*
* see ./enoc_pack.v
*
* see ./emesh_pack.v
*
******************************************************************************/
module enoc_decode
module emesh_decode
(
//Packet Command
input [15:0] cmd_in,
@ -26,15 +26,15 @@ module enoc_decode
output [2:0] cmd_size,
output [7:0] cmd_user
);
//############################################
// Command Decode
//############################################
//Writes
assign cmd_write = ~cmd_in[3];
assign cmd_write = ~cmd_in[3];
assign cmd_write_stop = cmd_in[3:0]==1001;
//Reads/atomics
assign cmd_read = cmd_in[3:0]==1000;
assign cmd_atomic_cas = cmd_in[3:0]==1011;
@ -48,8 +48,5 @@ module enoc_decode
assign cmd_length[3:0] = cmd_in[7:4];
assign cmd_size[2:0] = cmd_in[10:8];
assign cmd_user[7:0] = cmd_in[15:8];
endmodule // enoc_decode

View File

@ -0,0 +1,242 @@
/*******************************************************************************
* Function: SRAM with EMESH interface
* Author: Andreas Olofsson
* License: MIT (see LICENSE file in OH! repository)
*
******************************************************************************/
module emesh_memory
# (parameter AW = 32, // address width
parameter PW = 104, // packet width
parameter IDW = 12, // ID width
parameter DEPTH = 65536, // memory depth
parameter FILENAME = "log", // instance name
parameter EN_WAIT = 0, // 0=disable random wait
parameter EN_MON = 0, // 0=disable monitor
parameter WAIT_MASK = 32'h0000000F // range limiter for wait signal
)
(// clk,reset
input clk,
input nreset,
input [IDW-1:0] coreid,
// incoming read/write
input valid_in,
input [PW-1:0] packet_in,
output ready_out, //pushback
// back to mesh (readback data)
output reg valid_out,
output [PW-1:0] packet_out,
input ready_in //pushback
);
//derived parameters
localparam DW = AW; //always the same
parameter MAW = $clog2(DEPTH);
//###############
//# LOCAL WIRES
//##############
wire [MAW-1:0] addr;
wire [63:0] din;
wire [63:0] dout;
wire en;
wire mem_rd;
reg [7:0] wen;
reg write_out;
reg [1:0] datamode_out;
reg [4:0] ctrlmode_out;
reg [AW-1:0] dstaddr_out;
wire [AW-1:0] srcaddr_out;
wire [AW-1:0] data_out;
reg [2:0] align_addr;
wire [DW-1:0] din_aligned;
wire [63:0] dout_aligned;
wire ready_random; //TODO: make random
wire ready_all;
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire cmd_atomic_add; // From p2e of emesh_unpack.v
wire cmd_atomic_and; // From p2e of emesh_unpack.v
wire cmd_atomic_or; // From p2e of emesh_unpack.v
wire cmd_atomic_xor; // From p2e of emesh_unpack.v
wire cmd_cas; // From p2e of emesh_unpack.v
wire [3:0] cmd_length; // From p2e of emesh_unpack.v
wire [3:0] cmd_opcode; // From p2e of emesh_unpack.v
wire cmd_read; // From p2e of emesh_unpack.v
wire [2:0] cmd_size; // From p2e of emesh_unpack.v
wire [7:0] cmd_user; // From p2e of emesh_unpack.v
wire cmd_write; // From p2e of emesh_unpack.v
wire cmd_write_stop; // From p2e of emesh_unpack.v
wire [2*AW-1:0] data; // From p2e of emesh_unpack.v
wire [AW-1:0] dstaddr; // From p2e of emesh_unpack.v
wire [AW-1:0] srcaddr; // From p2e of emesh_unpack.v
// End of automatics
emesh_unpack #(.AW(AW),
.PW(PW))
p2e (/*AUTOINST*/
// Outputs
.cmd_write (cmd_write),
.cmd_write_stop (cmd_write_stop),
.cmd_read (cmd_read),
.cmd_atomic_add (cmd_atomic_add),
.cmd_atomic_and (cmd_atomic_and),
.cmd_atomic_or (cmd_atomic_or),
.cmd_atomic_xor (cmd_atomic_xor),
.cmd_cas (cmd_cas),
.cmd_opcode (cmd_opcode[3:0]),
.cmd_length (cmd_length[3:0]),
.cmd_size (cmd_size[2:0]),
.cmd_user (cmd_user[7:0]),
.dstaddr (dstaddr[AW-1:0]),
.srcaddr (srcaddr[AW-1:0]),
.data (data[2*AW-1:0]),
// Inputs
.packet_in (packet_in[PW-1:0]));
// Ready/valid
assign ready_all = (ready_random | ready_in);
assign en = valid_in & ready_all;
assign mem_rd = (valid_in & ~write_in & ready_all);
//Pushback Circuit (pass through problems?)
assign readt_out = ready_all;// & valid_in
//Address-in (shifted by three bits, 64 bit wide memory)
assign addr[MAW-1:0] = dstaddr[MAW+2:3];
//Shift up
assign din_aligned[31:0] = (cmd_size[2:0]==3'b000) ? {(4){data[7:0]}} :
(cmd_size[2:0]==3'b001) ? {(2){data[15:0]}} :
data_in[31:0];
//Data-in (hardoded width)
assign din[63:0] =(cmd_size[2:0]==3'b011) ? {srcaddr[31:0],din_aligned[31:0]}:
{din_aligned[31:0],din_aligned[31:0]};
//Write mask
always@*
casez({cmd_write, cmd_size[1:0],dstaddr[2:0]})
//Byte
6'b100000 : wen[7:0] = 8'b00000001;
6'b100001 : wen[7:0] = 8'b00000010;
6'b100010 : wen[7:0] = 8'b00000100;
6'b100011 : wen[7:0] = 8'b00001000;
6'b100100 : wen[7:0] = 8'b00010000;
6'b100101 : wen[7:0] = 8'b00100000;
6'b100110 : wen[7:0] = 8'b01000000;
6'b100111 : wen[7:0] = 8'b10000000;
//Short
6'b10100? : wen[7:0] = 8'b00000011;
6'b10101? : wen[7:0] = 8'b00001100;
6'b10110? : wen[7:0] = 8'b00110000;
6'b10111? : wen[7:0] = 8'b11000000;
//Word
6'b1100?? : wen[7:0] = 8'b00001111;
6'b1101?? : wen[7:0] = 8'b11110000;
//Double
6'b111??? : wen[7:0] = 8'b11111111;
default : wen[7:0] = 8'b00000000;
endcase // casez ({write, datamode_in[1:0],addr_in[2:0]})
//Single ported memory
defparam mem.N=64;
defparam mem.DEPTH=DEPTH;
oh_memory_sp mem(
// Inputs
.clk (clk),
.en (en),
.we (cmd_write),
.wem ({
{(8){wen[7]}},
{(8){wen[6]}},
{(8){wen[5]}},
{(8){wen[4]}},
{(8){wen[3]}},
{(8){wen[2]}},
{(8){wen[1]}},
{(8){wen[0]}}
}
),
.addr (addr[MAW-1:0]),
.din (din[63:0]),
.dout (dout[63:0]),
.vdd (1'b1),
.vddio (1'b1),
.memrepair(8'b0),
.memconfig(8'b0),
.bist_en (1'b0),
.bist_we (1'b0),
.bist_wem (64'b0),
.bist_addr({(MAW){1'b0}}),
.bist_din (64'b0)
);
//Outgoing transaction
always @ (posedge clk or negedge nreset)
if(!nreset)
valid_out <=1'b0;
else
begin
valid_out <= mem_rd;
write_out <= 1'b1;
align_addr[2:0] <= dstaddr[2:0];
datamode_out[1:0] <= datamode[1:0];
ctrlmode_out[4:0] <= ctrlmode[4:0];
dstaddr_out[AW-1:0] <= srcaddr[AW-1:0];
end
//Data alignment for readback
emesh_rdalign emesh_rdalign (// Outputs
.data_out (dout_aligned[63:0]),
// Inputs
.datamode (datamode_out[1:0]),
.addr (align_addr[2:0]),
.data_in (dout[63:0]));
assign srcaddr_out[AW-1:0] = (datamode_out[1:0]==2'b11) ? dout[63:32] : 32'b0;
assign data_out[31:0] = dout_aligned[31:0];
//Concatenate
emesh_pack #(.AW(AW),
.PW(PW))
e2p (// Outputs
.packet_out (packet_out[PW-1:0]),
// Inputs
.opcode_in (cmd_opcode[3:0]),
.length_in (cmd_length[3:0]),
.size_in (cmd_size[2:0]),
.user_in (cmd_user[7:3]),
.dstaddr_in (dstaddr[AW-1:0]),
.srcaddr_in (srcaddr[AW-1:0]),
.data_in (data[2*AW-1:0]));
// Traffic monitor
emesh_monitor #(.PW(PW),
.FILENAME(FILENAME),
.ENABLE(EN_MON))
emesh_monitor (.dut_valid (valid_in & write_in),
.dut_packet (packet_in[PW-1:0]),
.ready_in (ready_random),
.clk (clk),
.nreset (nreset));
//Random wait generator //TODO: make this a module
oh_pulse oh_pulse(// Outputs
.out (pulse),
// Inputs
.clk (clk),
.nreset (nreset),
.en (1'b1),
.mask (WAIT_MASK));
if(EN_MON)
assign ready_random = pulse;
else
assign ready_random = 1'b1;
endmodule // emesh_memory
// Local Variables:
// verilog-library-directories:("." "../dv" "../../stdlib/hdl/")
// End:

View File

@ -8,7 +8,8 @@
/* verilator lint_off STMTDLY */
module emesh_monitor
# (parameter PW = 104, // packet width
parameter FILENAME = "UNDEFINED" // filename
parameter FILENAME = "UNDEFINED", // filename
parameter ENABLE = 0 // enable block
)
(
//clock and reset
@ -20,34 +21,46 @@ module emesh_monitor
input ready_in
);
`ifdef DEBUG
generate
if(ENABLE)
begin
//core name for trace
reg [31:0] ftrace;
reg [255:0] tracefile;
//core name for trace
reg [31:0] ftrace;
reg [255:0] tracefile;
initial
begin
#10
$sformat(tracefile,"%0s_%0h%s",FILENAME);
ftrace = $fopen({tracefile}, "w");
end
//Dumps into
initial
begin
//TODO: Figure out these delays
#10
//index should be core ID
$sformat(tracefile,"%0s_%0h%s",FILENAME);
ftrace = $fopen({tracefile}, "w");
end
always @ (posedge clk)
if(nreset & dut_valid & ready_in)
if (PW==112) begin: p112
$fwrite(ftrace, "%h_%h_%h_%h\n",
dut_packet[110:80],
dut_packet[79:48],
dut_packet[47:16],
dut_packet[15:0]);
end
else if (PW==144) begin: p144
$fwrite(ftrace, "%h_%h_%h_%h\n",
dut_packet[143:112],
dut_packet[111:48],
dut_packet[47:16],
dut_packet[15:0]);
end
else if (PW==208) begin: p208
$fwrite(ftrace, "%h_%h_%h_%h_%h\n",
dut_packet[207:144],
dut_packet[143:112],
dut_packet[111:48],
dut_packet[47:16],
dut_packet[15:0]);
end
always @ (posedge clk)
if(nreset & dut_valid & ready_in)
if (PW==112) begin: p112
$fwrite(ftrace, "%h_%h_%h_%h\n",dut_packet[110:80],dut_packet[79:48],dut_packet[47:16],dut_packet[15:0]);
end
else if (PW==144) begin: p144
$fwrite(ftrace, "%h_%h_%h_%h\n",dut_packet[143:112],dut_packet[111:48],dut_packet[47:16],dut_packet[15:0]);
end
else if (PW==208) begin: p208
$fwrite(ftrace, "%h_%h_%h_%h_%h\n",dut_packet[207:144],dut_packet[143:112],dut_packet[111:48],dut_packet[47:16],dut_packet[15:0]);
end
`endif // `ifdef DEBUG
end
endgenerate
endmodule // emesh_monitor

View File

@ -1,12 +1,12 @@
/*******************************************************************************
* Function: Memory Mapped Transaction --> Packet Converter
* Author: Andreas Olofsson
* Function: Memory Mapped Transaction --> Packet Converter
* Author: Andreas Olofsson
* License: MIT (see LICENSE file in OH! repository)
*
* Documentation:
*
*
* The following table shows the field mapping for different AW's:
*
*
* | Packet | AW16 | AW32 | AW64 | AW128 |
* |---------|---------|----------|--------|---------|
* | 15:0 | DA,CMD | CMD | CMD | CMD |
@ -25,17 +25,17 @@
* | 335:304 | **** | **** | **** | D5 |
* | 367:336 | **** | **** | **** | D6 |
* | 399:368 | **** | **** | **** | D7 |
*
*
* The following list shows the widths supported for each AW
*
*
* |Packet | AW16 | AW32 | AW64 | AW128 |
* |---------------|-------|--------|--------|--------|
* |minimum | 40 | 72+8 | 136+8 | 264+8 |
* |double/atomics | -- | 104+8 | 200+8 | 392+8 |
*
*
* The command field has the following options:
*
*
*
*
* | Command[15:0] | 15:11 | 10:8 | 7:4 | 3:0 |
* |-----------------|-----------|-----------|----------|------|
* | WRITE-START | USER[7:3] | SIZE[2:0] | LEN[3:0] | 0000 |
@ -55,7 +55,7 @@
* | ATOMIC-AND | USER[7:3] | SIZE[2:0] | LEN[3:0] | 1101 |
* | ATOMIC-OR | USER[7:3] | SIZE[2:0] | LEN[3:0] | 1110 |
* | ATOMIC-XOR | USER[7:3] | SIZE[2:0] | LEN[3:0] | 1111 |
*
*
* SIZE DECODE:
* 000=8b
* 001=16b
@ -65,20 +65,20 @@
* 101=256b
* 110=512b
* 111=1024b
*
*
* LENGTH DECODE:
* 0000=1 beat (single transaction)
* 0001=2 beat
* ...
* 1111=16 beats
*
*
* AW32/AW64/AW128 formats are compatible
* AW16 format is a standalone format not compatible with any other
* All transactions are LSB aligned
* All transactions are LSB aligned
* No return address for AW16 (point to point)
*
*
******************************************************************************/
module enoc_pack
module emesh_pack
#(parameter AW = 64,
parameter PW = 144)
(
@ -94,19 +94,19 @@ module enoc_pack
//Output packet
output [PW-1:0] packet_out
);
//############################################
// Command Field
//############################################
wire [15:0] cmd_out;
assign cmd_out[3:0] = opcode_in[3:0];
assign cmd_out[3:0] = opcode_in[3:0];
assign cmd_out[7:4] = length_in[3:0];
assign cmd_out[10:8] = size_in[2:0];
assign cmd_out[15:11] = user_in[7:3];
//Decode (only write indicator needed)
enoc_decode enoc_decode (//Inputs
emesh_decode enoc_decode (//Inputs
.cmd_in (cmd_out[15:0]),
// Outputs
.cmd_write (cmd_write),
@ -121,7 +121,7 @@ module enoc_pack
.cmd_length (),
.cmd_size (),
.cmd_user ());
generate
//############################
// 16-Bit ("lite/apb like")
@ -145,13 +145,13 @@ module enoc_pack
if(PW==80) begin: p80
assign packet_out[15:0] = cmd_out[15:0];
assign packet_out[47:16] = dstaddr_in[31:0];
assign packet_out[79:48] = cmd_write ? data_in[31:0] :
assign packet_out[79:48] = cmd_write ? data_in[31:0] :
srcaddr_in[31:0];
end
else if(PW==112) begin: p112
assign packet_out[15:0] = cmd_out[15:0];
assign packet_out[47:16] = dstaddr_in[31:0];
assign packet_out[79:48] = cmd_write ? data_in[31:0] :
assign packet_out[79:48] = cmd_write ? data_in[31:0] :
srcaddr_in[31:0];
assign packet_out[111:80] = data_in[63:32];
end
@ -167,14 +167,14 @@ module enoc_pack
if(PW==144) begin: p144
assign packet_out[15:0] = cmd_out[15:0];
assign packet_out[47:16] = dstaddr_in[31:0];
assign packet_out[111:48] = cmd_write ? data_in[63:0] :
assign packet_out[111:48] = cmd_write ? data_in[63:0] :
srcaddr_in[63:0];
assign packet_out[143:112] = dstaddr_in[63:32];
end
else if(PW==208) begin: p208
assign packet_out[15:0] = cmd_out[15:0];
assign packet_out[47:16] = dstaddr_in[31:0];
assign packet_out[111:48] = cmd_write ? data_in[63:0] :
assign packet_out[111:48] = cmd_write ? data_in[63:0] :
srcaddr_in[63:0];
assign packet_out[143:112] = dstaddr_in[63:32];
assign packet_out[207:144] = data_in[127:64];
@ -191,20 +191,20 @@ module enoc_pack
if(PW==272) begin: p272
assign packet_out[15:0] = cmd_out[15:0];
assign packet_out[47:16] = dstaddr_in[31:0];
assign packet_out[111:48] = cmd_write ? data_in[63:0] :
assign packet_out[111:48] = cmd_write ? data_in[63:0] :
srcaddr_in[63:0];
assign packet_out[143:112] = dstaddr_in[63:32];
assign packet_out[207:144] = cmd_write ? data_in[127:64] :
assign packet_out[207:144] = cmd_write ? data_in[127:64] :
srcaddr_in[127:64];
assign packet_out[271:208] = dstaddr_in[127:64];
end
else if(PW==400) begin: p400
assign packet_out[15:0] = cmd_out[15:0];
assign packet_out[47:16] = dstaddr_in[31:0];
assign packet_out[111:48] = cmd_write ? data_in[63:0] :
assign packet_out[111:48] = cmd_write ? data_in[63:0] :
srcaddr_in[63:0];
assign packet_out[143:112] = dstaddr_in[63:32];
assign packet_out[207:144] = cmd_write ? data_in[127:64] :
assign packet_out[207:144] = cmd_write ? data_in[127:64] :
srcaddr_in[127:64];
assign packet_out[271:208] = dstaddr_in[127:64];
assign packet_out[399:272] = data_in[255:128];
@ -214,6 +214,5 @@ module enoc_pack
$display ("Combo not supported (PW=%ds AW==%ds)", PW,AW);
end
end // block: aw128
endgenerate
endmodule // emesh2packet
endgenerate
endmodule // emesh_pack

View File

@ -1,15 +1,15 @@
/*******************************************************************************
* Function: Packet-->Memory Mapped Transaction Converter
* Author: Andreas Olofsson
* Function: Packet-->Memory Mapped Transaction Converter
* Author: Andreas Olofsson
* License: MIT (see LICENSE file in OH! repository)
*
* Documentation:
*
* see ./enoc_pack.v for packet formatting
*
*
* see ./emesh_pack.v for packet formatting
*
******************************************************************************/
module enoc_unpack
#(parameter AW = 32, // address width
module emesh_unpack
#(parameter AW = 32, // address width
parameter PW = 104) // packet width
(
//Input packet
@ -42,21 +42,21 @@ module enoc_unpack
// Command Decode
//############################################
enoc_decode enoc_decode (//Input
.cmd_in (cmd[15:0]),
// Outputs
.cmd_write (cmd_write),
.cmd_write_stop (cmd_write_stop),
.cmd_read (cmd_read),
.cmd_cas (cmd_cas),
.cmd_atomic_add (cmd_atomic_add),
.cmd_atomic_and (cmd_atomic_and),
.cmd_atomic_or (cmd_atomic_or),
.cmd_atomic_xor (cmd_atomic_xor),
.cmd_opcode (cmd_opcode[3:0]),
.cmd_user (cmd_user[7:0]),
.cmd_length (cmd_length[3:0]),
.cmd_size (cmd_size[2:0]));
emesh_decode emesh_decode (//Input
.cmd_in (cmd[15:0]),
// Outputs
.cmd_write (cmd_write),
.cmd_write_stop (cmd_write_stop),
.cmd_read (cmd_read),
.cmd_cas (cmd_cas),
.cmd_atomic_add (cmd_atomic_add),
.cmd_atomic_and (cmd_atomic_and),
.cmd_atomic_or (cmd_atomic_or),
.cmd_atomic_xor (cmd_atomic_xor),
.cmd_opcode (cmd_opcode[3:0]),
.cmd_user (cmd_user[7:0]),
.cmd_length (cmd_length[3:0]),
.cmd_size (cmd_size[2:0]));
generate
//######################
// 16-Bit ("lite/apb like")
@ -83,7 +83,7 @@ module enoc_unpack
assign dstaddr[31:0] = packet_in[47:16];
assign srcaddr[31:0] = packet_in[79:48];
assign data[31:0] = packet_in[79:48];
assign data[63:32] = 32'b0;
assign data[63:32] = 32'b0;
end
else if(PW==112) begin: p112
assign cmd[15:0] = packet_in[15:0];
@ -106,7 +106,7 @@ module enoc_unpack
assign srcaddr[63:0] = packet_in[111:48];
assign data[127:0] = packet_in[111:48];
assign dstaddr[63:32] = packet_in[143:112];
assign data[127:64] = 64'b0;
assign data[127:64] = 64'b0;
end
else if(PW==208) begin: p208
assign cmd[15:0] = packet_in[15:0];
@ -134,7 +134,7 @@ module enoc_unpack
assign data[127:64] = packet_in[207:144];
assign srcaddr[127:64] = packet_in[207:144];
assign dstaddr[127:64] = packet_in[271:208];
assign data[255:128] = 128'b0;
assign data[255:128] = 128'b0;
end
else if(PW==400) begin: p400
assign cmd[15:0] = packet_in[15:0];
@ -152,10 +152,6 @@ module enoc_unpack
$display ("Combo not supported (PW=%ds AW==%ds)", PW,AW);
end
end // block: aw128
endgenerate
endgenerate
endmodule // enoc_unpack

View File

@ -1,46 +0,0 @@
/* verilator lint_off STMTDLY */
module emesh_monitor(/*AUTOARG*/
// Inputs
clk, nreset, dut_access, dut_packet, ready_in, coreid
);
parameter PW = 104;
parameter IDW = 12;
parameter INDEX = 0;
parameter NAME = "not_declared";
//clock and reset
input clk;
input nreset;
//monitors transaction on the wire
input dut_access;
input [PW-1:0] dut_packet;
input ready_in;
input [IDW-1:0] coreid;
//core name for trace
reg [31:0] ftrace;
reg [255:0] tracefile;
//Dumps into
initial
begin
//TODO: Figure out these delays
#10
//index should be core ID
$sformat(tracefile,"%0s_%0h%s",NAME,coreid,".trace");
ftrace = $fopen({tracefile}, "w");
end
always @ (posedge clk or negedge nreset)
if(nreset & dut_access & ready_in)
begin
$fwrite(ftrace, "%h_%h_%h_%h\n",dut_packet[PW-1:72],dut_packet[71:40],dut_packet[39:8],dut_packet[7:0]);
//$display("%h_%h_%h_%h\n",dut_packet[PW-1:72],dut_packet[71:40],dut_packet[39:8],dut_packet[7:0]);
end
endmodule // dut_monitor

View File

@ -1,240 +0,0 @@
module ememory # (parameter AW = 32, // address width
parameter PW = 104, // packet width
parameter IDW = 12, // ID width
parameter DEPTH = 65536, // memory depth
parameter NAME = "emem", // instance name
parameter WAIT = 0, // enable random wait
parameter MON = 0 // enable monitor monitor
)
(// clk,reset
input clk,
input nreset,
input [IDW-1:0] coreid,
// incoming read/write
input access_in,
input [PW-1:0] packet_in,
output ready_out, //pushback
// back to mesh (readback data)
output reg access_out,
output [PW-1:0] packet_out,
input ready_in //pushback
);
//derived parameters
localparam DW = AW; //always the same
parameter MAW = $clog2(DEPTH);
//###############
//# LOCAL WIRES
//##############
wire [MAW-1:0] addr;
wire [63:0] din;
wire [63:0] dout;
wire en;
wire mem_rd;
reg [7:0] wen;
reg write_out;
reg [1:0] datamode_out;
reg [4:0] ctrlmode_out;
reg [AW-1:0] dstaddr_out;
wire [AW-1:0] srcaddr_out;
wire [AW-1:0] data_out;
reg [2:0] align_addr;
wire [DW-1:0] din_aligned;
wire [63:0] dout_aligned;
wire ready_random; //TODO: make random
wire ready_all;
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire [4:0] ctrlmode_in; // From p2e of packet2emesh.v
wire [AW-1:0] data_in; // From p2e of packet2emesh.v
wire [1:0] datamode_in; // From p2e of packet2emesh.v
wire [AW-1:0] dstaddr_in; // From p2e of packet2emesh.v
wire [AW-1:0] srcaddr_in; // From p2e of packet2emesh.v
wire write_in; // From p2e of packet2emesh.v
// End of automatics
packet2emesh #(.AW(AW),
.PW(PW))
p2e (/*AUTOINST*/
// Outputs
.write_in (write_in),
.datamode_in (datamode_in[1:0]),
.ctrlmode_in (ctrlmode_in[4:0]),
.dstaddr_in (dstaddr_in[AW-1:0]),
.srcaddr_in (srcaddr_in[AW-1:0]),
.data_in (data_in[AW-1:0]),
// Inputs
.packet_in (packet_in[PW-1:0]));
//Access-in
assign en = access_in & ready_all & ready_all;
assign mem_rd = (access_in & ~write_in & ready_all);
//Pushback Circuit (pass through problems?)
assign ready_all = (ready_random | ready_in);
assign readt_out = ready_all;// & access_in
//Address-in (shifted by three bits, 64 bit wide memory)
assign addr[MAW-1:0] = dstaddr_in[MAW+2:3];
//Shift up
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],din_aligned[31:0]}:
{din_aligned[31:0],din_aligned[31:0]};
//Write mask
//TODO: make module
always@*
casez({write_in, datamode_in[1:0],dstaddr_in[2:0]})
//Byte
6'b100000 : wen[7:0] = 8'b00000001;
6'b100001 : wen[7:0] = 8'b00000010;
6'b100010 : wen[7:0] = 8'b00000100;
6'b100011 : wen[7:0] = 8'b00001000;
6'b100100 : wen[7:0] = 8'b00010000;
6'b100101 : wen[7:0] = 8'b00100000;
6'b100110 : wen[7:0] = 8'b01000000;
6'b100111 : wen[7:0] = 8'b10000000;
//Short
6'b10100? : wen[7:0] = 8'b00000011;
6'b10101? : wen[7:0] = 8'b00001100;
6'b10110? : wen[7:0] = 8'b00110000;
6'b10111? : wen[7:0] = 8'b11000000;
//Word
6'b1100?? : wen[7:0] = 8'b00001111;
6'b1101?? : wen[7:0] = 8'b11110000;
//Double
6'b111??? : wen[7:0] = 8'b11111111;
default : wen[7:0] = 8'b00000000;
endcase // casez ({write, datamode_in[1:0],addr_in[2:0]})
//Single ported memory
defparam mem.DW=64;
defparam mem.DEPTH=DEPTH;
oh_memory_sp mem(
// Inputs
.clk (clk),
.en (en),
.we (write_in),
.wem ({
{(8){wen[7]}},
{(8){wen[6]}},
{(8){wen[5]}},
{(8){wen[4]}},
{(8){wen[3]}},
{(8){wen[2]}},
{(8){wen[1]}},
{(8){wen[0]}}
}
),
.addr (addr[MAW-1:0]),
.din (din[63:0]),
.dout (dout[63:0]),
.vdd (1'b1),
.vddm (1'b1),
.memrepair(8'b0),
.memconfig(8'b0),
.bist_en (1'b0),
.bist_we (1'b0),
.bist_wem (64'b0),
.bist_addr({(MAW){1'b0}}),
.bist_din (64'b0)
);
//Outgoing transaction
always @ (posedge clk or negedge nreset)
if(!nreset)
access_out <=1'b0;
else
begin
access_out <= mem_rd;
write_out <= 1'b1;
align_addr[2:0] <= dstaddr_in[2:0];
datamode_out[1:0] <= datamode_in[1:0];
ctrlmode_out[4:0] <= ctrlmode_in[4:0];
dstaddr_out[AW-1:0] <= srcaddr_in[AW-1:0];
end
//Data alignment for readback
emesh_rdalign emesh_rdalign (// Outputs
.data_out (dout_aligned[63:0]),
// Inputs
.datamode (datamode_out[1:0]),
.addr (align_addr[2:0]),
.data_in (dout[63:0]));
assign srcaddr_out[AW-1:0] = (datamode_out[1:0]==2'b11) ? dout[63:32] : 32'b0;
assign data_out[31:0] = dout_aligned[31:0];
//Concatenate
emesh2packet #(.AW(AW),
.PW(PW))
e2p (
/*AUTOINST*/
// Outputs
.packet_out (packet_out[PW-1:0]),
// Inputs
.write_out (write_out),
.datamode_out (datamode_out[1:0]),
.ctrlmode_out (ctrlmode_out[4:0]),
.dstaddr_out (dstaddr_out[AW-1:0]),
.data_out (data_out[AW-1:0]),
.srcaddr_out (srcaddr_out[AW-1:0]));
`ifdef TARGET_SIM
generate
if(MON)
begin
emesh_monitor #(.PW(PW),
.INDEX(1),
.NAME(NAME),
.IDW(IDW)
)
emesh_monitor (.dut_access (access_in & write_in),
.dut_packet (packet_in[PW-1:0]),
.ready_in (ready_random),
/*AUTOINST*/
// Inputs
.clk (clk),
.nreset (nreset),
.coreid (coreid[IDW-1:0]));
end // if (MON)
endgenerate
`endif
//Random wait generator //TODO: make this a module
generate
if(WAIT)
begin
reg [8:0] ready_counter;
always @ (posedge clk or negedge nreset)
if(!nreset)
ready_counter[8:0] <= 'b0;
else
ready_counter[8:0] <= ready_counter+1'b1;
assign ready_random = (|ready_counter[5:0]);//(|ready_counter[3:0]);//1'b0;
end
else
begin
assign ready_random = 1'b0;
end // else: !if(WAIT)
endgenerate
endmodule // emesh_memory
// Local Variables:
// verilog-library-directories:("." "../dv" )
// End: