mirror of
https://github.com/aolofsson/oh.git
synced 2025-01-17 20:02:53 +08:00
a68bba1572
- Removed the cfgif block, too confusing. There is a good lesson here. Probably the n'th time I that I have been overzealous about reuse. When you end up adding a parameter to a block that duplicates the logic 2X it's always better to create two separate blocks... - Changed the register access interface to packet format - Change the priority on the etx_arbiter to pick read responses first - Removed redundant signals - Took away the read resonse bypass on remap in tx for now.. - Removed defparams (convention) - Unified wait signal on tx - Fixed cfg wait -
234 lines
6.1 KiB
Verilog
234 lines
6.1 KiB
Verilog
|
|
module ememory(/*AUTOARG*/
|
|
// Outputs
|
|
wait_out, access_out, packet_out,
|
|
// Inputs
|
|
clk, nreset, coreid, access_in, packet_in, wait_in
|
|
);
|
|
|
|
|
|
parameter AW = 32;
|
|
parameter IDW = 12;
|
|
parameter DEPTH = 65536;
|
|
parameter MAW = $clog2(DEPTH);
|
|
parameter NAME = "emem";
|
|
parameter WAIT = 0; //turns on random wait circuit
|
|
parameter MON = 0; //turns on monitor
|
|
|
|
//derived parameters
|
|
localparam DW = AW; //always the same
|
|
localparam PW = 2*AW+40;//packet width
|
|
|
|
//Basic Interface
|
|
input clk;
|
|
input nreset;
|
|
input [IDW-1:0] coreid;
|
|
|
|
//incoming read/write
|
|
input access_in;
|
|
input [PW-1:0] packet_in;
|
|
output wait_out; //pushback
|
|
|
|
//back to mesh (readback data)
|
|
output access_out;
|
|
output [PW-1:0] packet_out;
|
|
input wait_in; //pushback
|
|
|
|
wire [MAW-1:0] addr;
|
|
wire [63:0] din;
|
|
wire [63:0] dout;
|
|
wire en;
|
|
wire mem_rd;
|
|
reg [7:0] wen;
|
|
|
|
//State
|
|
reg access_out;
|
|
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 write_in;
|
|
wire [1:0] datamode_in;
|
|
wire [4:0] ctrlmode_in;
|
|
wire [AW-1:0] dstaddr_in;
|
|
wire [DW-1:0] data_in;
|
|
wire [AW-1:0] srcaddr_in;
|
|
wire [DW-1:0] din_aligned;
|
|
wire [63:0] dout_aligned;
|
|
wire wait_random; //TODO: make random
|
|
wire wait_all;
|
|
|
|
packet2emesh #(.AW(AW))
|
|
p2e (
|
|
.write_in (write_in),
|
|
.datamode_in (datamode_in[1:0] ),
|
|
.ctrlmode_in (ctrlmode_in[4:0]),
|
|
.dstaddr_in (dstaddr_in[AW-1:0]),
|
|
.data_in (data_in[DW-1:0]),
|
|
.srcaddr_in (srcaddr_in[AW-1:0]),
|
|
.packet_in (packet_in[PW-1:0])
|
|
);
|
|
|
|
//Access-in
|
|
assign en = access_in & ~wait_all & ~wait_all;
|
|
assign mem_rd = (access_in & ~write_in & ~wait_all);
|
|
|
|
|
|
//Pushback Circuit (pass through problems?)
|
|
assign wait_all = (wait_random | wait_in);
|
|
assign wait_out = wait_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])
|
|
);
|
|
|
|
//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))
|
|
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]),
|
|
.wait_in (wait_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] wait_counter;
|
|
always @ (posedge clk or negedge nreset)
|
|
if(!nreset)
|
|
wait_counter[8:0] <= 'b0;
|
|
else
|
|
wait_counter[8:0] <= wait_counter+1'b1;
|
|
assign wait_random = (|wait_counter[5:0]);//(|wait_counter[3:0]);//1'b0;
|
|
end
|
|
else
|
|
begin
|
|
assign wait_random = 1'b0;
|
|
end // else: !if(WAIT)
|
|
endgenerate
|
|
|
|
|
|
endmodule // emesh_memory
|
|
// Local Variables:
|
|
// verilog-library-directories:("." "../dv" )
|
|
// End:
|
|
|
|
|
|
|