mirror of
https://github.com/aolofsson/oh.git
synced 2025-01-30 02:32:53 +08:00
Fixing mutual exclusive bug on receiver
-When a read response is detected, there should be no spurious transactions to the RD/WR request fifos. -Move the "filter" backt to the erx_protocol block -Removed the remap bypass signal (was hacky) -Passes simulations again..
This commit is contained in:
parent
21686d31cc
commit
ede8656081
@ -2,10 +2,9 @@
|
||||
module erx_arbiter (/*AUTOARG*/
|
||||
// Outputs
|
||||
rx_rd_wait, rx_wr_wait, edma_wait, ecfg_wait, rxwr_access,
|
||||
rxwr_packet, rxrd_access, rxrd_packet,
|
||||
rxrr_access, rxrr_packet,
|
||||
rxwr_packet, rxrd_access, rxrd_packet, rxrr_access, rxrr_packet,
|
||||
// Inputs
|
||||
erx_access, erx_packet, emmu_access, emmu_packet, edma_access,
|
||||
erx_rr_access, erx_packet, emmu_access, emmu_packet, edma_access,
|
||||
edma_packet, ecfg_access, ecfg_packet, timeout, rxwr_wait,
|
||||
rxrd_wait, rxrr_wait
|
||||
);
|
||||
@ -17,13 +16,13 @@ module erx_arbiter (/*AUTOARG*/
|
||||
parameter RFAW = 6;
|
||||
|
||||
|
||||
//From IO (for rr)
|
||||
input erx_access;
|
||||
//From IO (for rr)
|
||||
input erx_rr_access;
|
||||
input [PW-1:0] erx_packet;
|
||||
output rx_rd_wait; //for IO
|
||||
output rx_wr_wait; //for IO
|
||||
|
||||
//From EMMU
|
||||
//From EMMU (writes)
|
||||
input emmu_access;
|
||||
input [PW-1:0] emmu_packet;
|
||||
|
||||
@ -57,83 +56,41 @@ module erx_arbiter (/*AUTOARG*/
|
||||
|
||||
//wires
|
||||
wire emmu_write;
|
||||
wire [1:0] emmu_datamode;
|
||||
wire [3:0] emmu_ctrlmode;
|
||||
wire [31:0] emmu_dstaddr;
|
||||
wire [31:0] emmu_srcaddr;
|
||||
wire [31:0] emmu_data;
|
||||
wire emmu_read;
|
||||
|
||||
wire erx_write;
|
||||
wire [1:0] erx_datamode;
|
||||
wire [3:0] erx_ctrlmode;
|
||||
wire [31:0] erx_dstaddr;
|
||||
wire [31:0] erx_srcaddr;
|
||||
wire [31:0] erx_data;
|
||||
wire erx_read;
|
||||
wire erx_rr_access;
|
||||
|
||||
wire [11:0] myid;
|
||||
|
||||
//####################################
|
||||
//Splicing pakets
|
||||
//####################################
|
||||
assign myid[11:0] = ID;
|
||||
|
||||
packet2emesh p2e_erx (// Outputs
|
||||
.access_out (),
|
||||
.write_out (erx_write),
|
||||
.datamode_out (erx_datamode[1:0]),
|
||||
.ctrlmode_out (erx_ctrlmode[3:0]),
|
||||
.dstaddr_out (erx_dstaddr[AW-1:0]),
|
||||
.data_out (erx_data[DW-1:0]),
|
||||
.srcaddr_out (erx_srcaddr[AW-1:0]),
|
||||
// Inputs
|
||||
.packet_in (erx_packet[PW-1:0])
|
||||
);
|
||||
|
||||
packet2emesh p2e_mmu (// Outputs
|
||||
.access_out (),
|
||||
.write_out (emmu_write),
|
||||
.datamode_out (emmu_datamode[1:0]),
|
||||
.ctrlmode_out (emmu_ctrlmode[3:0]),
|
||||
.dstaddr_out (emmu_dstaddr[AW-1:0]),
|
||||
.data_out (emmu_data[DW-1:0]),
|
||||
.srcaddr_out (emmu_srcaddr[AW-1:0]),
|
||||
// Inputs
|
||||
.packet_in (emmu_packet[PW-1:0])
|
||||
);
|
||||
|
||||
//####################################
|
||||
//Read response path, bypass mmu
|
||||
//####################################
|
||||
|
||||
assign erx_rr_access = (erx_access &
|
||||
erx_write &
|
||||
(erx_dstaddr[31:20] == myid[11:0]) &
|
||||
(erx_dstaddr[19:16] == `EGROUP_RR) // Not sure about this...
|
||||
);
|
||||
|
||||
assign rxrr_access = erx_rr_access |
|
||||
ecfg_access;
|
||||
//####################################
|
||||
//Read response path (from IO or cfg)
|
||||
//####################################
|
||||
|
||||
assign rxrr_access = erx_rr_access |
|
||||
ecfg_access;
|
||||
|
||||
assign rxrr_packet[PW-1:0] = erx_rr_access ? erx_packet[PW-1:0] :
|
||||
ecfg_packet[PW-1:0];
|
||||
|
||||
assign ecfg_wait = erx_rr_access;
|
||||
assign ecfg_wait = erx_rr_access;
|
||||
|
||||
//####################################
|
||||
//Write Path (direct)
|
||||
//####################################
|
||||
assign emmu_write = emmu_packet[1];
|
||||
|
||||
assign rxwr_access = emmu_access &
|
||||
emmu_write;
|
||||
|
||||
assign rxwr_access = emmu_access & emmu_write;
|
||||
|
||||
assign rxwr_packet[PW-1:0] = emmu_packet[PW-1:0];
|
||||
|
||||
//####################################
|
||||
//Read Path
|
||||
//Read Request Path
|
||||
//####################################
|
||||
|
||||
assign emmu_read = (emmu_access & ~emmu_write);
|
||||
assign emmu_read = emmu_access & ~emmu_write;
|
||||
|
||||
assign rxrd_access = emmu_read | edma_access;
|
||||
|
||||
@ -149,7 +106,8 @@ module erx_arbiter (/*AUTOARG*/
|
||||
assign edma_wait = rxrd_wait | emmu_read;
|
||||
assign erx_cfg_wait = rxwr_wait | rxrr_wait;
|
||||
|
||||
endmodule // erx_disty
|
||||
endmodule // erx_arbiter
|
||||
|
||||
// Local Variables:
|
||||
// verilog-library-directories:("." "../../common/hdl" "../../emmu/hdl")
|
||||
// End:
|
||||
@ -158,7 +116,7 @@ endmodule // erx_disty
|
||||
/*
|
||||
This file is part of the Parallella Project.
|
||||
|
||||
Copyright (C) 2014 Adapteva, Inc.
|
||||
Copyright (C) 2015 Adapteva, Inc.
|
||||
Contributed by Andreas Olofsson <andreas@adapteva.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
@ -61,8 +61,9 @@ module erx_core (/*AUTOARG*/
|
||||
wire [PW-1:0] emesh_remap_packet; // From erx_remap of erx_remap.v
|
||||
wire emmu_access; // From erx_mmu of emmu.v
|
||||
wire [PW-1:0] emmu_packet; // From erx_mmu of emmu.v
|
||||
wire erx_access; // From erx_protocol of erx_protocol.v
|
||||
wire [PW-1:0] erx_packet; // From erx_protocol of erx_protocol.v
|
||||
wire erx_rdwr_access; // From erx_protocol of erx_protocol.v
|
||||
wire erx_rr_access; // From erx_protocol of erx_protocol.v
|
||||
wire [14:0] mi_addr; // From erx_cfgif of ecfg_if.v
|
||||
wire [DW-1:0] mi_cfg_dout; // From erx_cfg of erx_cfg.v
|
||||
wire mi_cfg_en; // From erx_cfgif of ecfg_if.v
|
||||
@ -75,7 +76,6 @@ module erx_core (/*AUTOARG*/
|
||||
wire mi_we; // From erx_cfgif of ecfg_if.v
|
||||
wire mmu_enable; // From erx_cfg of erx_cfg.v
|
||||
wire [31:0] remap_base; // From erx_cfg of erx_cfg.v
|
||||
wire remap_bypass; // From erx_protocol of erx_protocol.v
|
||||
wire [1:0] remap_mode; // From erx_cfg of erx_cfg.v
|
||||
wire [11:0] remap_pattern; // From erx_cfg of erx_cfg.v
|
||||
wire [11:0] remap_sel; // From erx_cfg of erx_cfg.v
|
||||
@ -102,9 +102,9 @@ module erx_core (/*AUTOARG*/
|
||||
defparam erx_protocol.ID=ID;
|
||||
erx_protocol erx_protocol (/*AUTOINST*/
|
||||
// Outputs
|
||||
.erx_access (erx_access),
|
||||
.erx_rdwr_access (erx_rdwr_access),
|
||||
.erx_rr_access (erx_rr_access),
|
||||
.erx_packet (erx_packet[PW-1:0]),
|
||||
.remap_bypass (remap_bypass),
|
||||
// Inputs
|
||||
.reset (reset),
|
||||
.rx_enable (rx_enable),
|
||||
@ -122,6 +122,7 @@ module erx_core (/*AUTOARG*/
|
||||
/*erx_remap AUTO_TEMPLATE (
|
||||
.emesh_\(.*\)_out (emesh_remap_\1[]),
|
||||
//Inputs
|
||||
.emesh_access_in (erx_rdwr_access),
|
||||
.emesh_\(.*\)_in (erx_\1[]),
|
||||
.mmu_en (ecfg_rx_mmu_enable),
|
||||
.emesh_packet_hi_out (),
|
||||
@ -136,13 +137,12 @@ module erx_core (/*AUTOARG*/
|
||||
// Inputs
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.emesh_access_in(erx_access), // Templated
|
||||
.emesh_access_in(erx_rdwr_access), // Templated
|
||||
.emesh_packet_in(erx_packet[PW-1:0]), // Templated
|
||||
.remap_mode (remap_mode[1:0]),
|
||||
.remap_sel (remap_sel[11:0]),
|
||||
.remap_pattern (remap_pattern[11:0]),
|
||||
.remap_base (remap_base[31:0]),
|
||||
.remap_bypass (remap_bypass),
|
||||
.rx_rd_wait (rx_rd_wait),
|
||||
.rx_wr_wait (rx_wr_wait));
|
||||
|
||||
@ -160,15 +160,14 @@ module erx_core (/*AUTOARG*/
|
||||
.wr_clk (clk),
|
||||
.mi_dout (mi_mmu_dout[DW-1:0]),
|
||||
.emesh_packet_hi_out (),
|
||||
.mmu_bp (remap_bypass),
|
||||
.mi_en (mi_mmu_en),
|
||||
.emesh_rd_wait (rx_rd_wait),
|
||||
.emesh_wr_wait (rx_wr_wait),
|
||||
);
|
||||
*/
|
||||
|
||||
emmu erx_mmu (
|
||||
/*AUTOINST*/
|
||||
emmu erx_mmu (.mmu_bp (1'b0),
|
||||
/*AUTOINST*/
|
||||
// Outputs
|
||||
.mi_dout (mi_mmu_dout[DW-1:0]), // Templated
|
||||
.emesh_access_out (emmu_access), // Templated
|
||||
@ -179,7 +178,6 @@ module erx_core (/*AUTOARG*/
|
||||
.rd_clk (clk), // Templated
|
||||
.wr_clk (clk), // Templated
|
||||
.mmu_en (mmu_enable), // Templated
|
||||
.mmu_bp (remap_bypass), // Templated
|
||||
.mi_en (mi_mmu_en), // Templated
|
||||
.mi_we (mi_we),
|
||||
.mi_addr (mi_addr[14:0]),
|
||||
@ -364,7 +362,7 @@ module erx_core (/*AUTOARG*/
|
||||
.rxrr_access (rxrr_access),
|
||||
.rxrr_packet (rxrr_packet[PW-1:0]),
|
||||
// Inputs
|
||||
.erx_access (erx_access),
|
||||
.erx_rr_access (erx_rr_access),
|
||||
.erx_packet (erx_packet[PW-1:0]),
|
||||
.emmu_access (emmu_access),
|
||||
.emmu_packet (emmu_packet[PW-1:0]),
|
||||
|
@ -1,3 +1,6 @@
|
||||
/*
|
||||
This block receives the IO transaction and converts to a 104 bit packet.
|
||||
*/
|
||||
`include "elink_constants.v"
|
||||
module erx_io (/*AUTOARG*/
|
||||
// Outputs
|
||||
|
@ -1,16 +1,11 @@
|
||||
/*
|
||||
########################################################################
|
||||
EPIPHANY eLink RX Protocol block
|
||||
########################################################################
|
||||
|
||||
This block takes the parallel output of the input deserializers, locates
|
||||
valid frame transitions, and decodes the bytes into standard eMesh
|
||||
protocol (104-bit transactions).
|
||||
This block handles the autoincrement needed for bursting and detects
|
||||
read responses
|
||||
*/
|
||||
|
||||
`include "elink_regmap.v"
|
||||
module erx_protocol (/*AUTOARG*/
|
||||
// Outputs
|
||||
erx_access, erx_packet, remap_bypass,
|
||||
erx_rdwr_access, erx_rr_access, erx_packet,
|
||||
// Inputs
|
||||
reset, rx_enable, clk, rx_packet, rx_burst, rx_access
|
||||
);
|
||||
@ -18,7 +13,7 @@ module erx_protocol (/*AUTOARG*/
|
||||
parameter AW = 32;
|
||||
parameter DW = 32;
|
||||
parameter PW = 104;
|
||||
parameter ID = 0;
|
||||
parameter ID = 12'h800; //link id
|
||||
|
||||
|
||||
// System reset input
|
||||
@ -32,15 +27,25 @@ module erx_protocol (/*AUTOARG*/
|
||||
input rx_access;
|
||||
|
||||
// Output to MMU / filter
|
||||
output erx_access;
|
||||
output erx_rdwr_access;
|
||||
output erx_rr_access;
|
||||
output [PW-1:0] erx_packet;
|
||||
output remap_bypass; //needed for remapping logic
|
||||
|
||||
|
||||
//wires
|
||||
reg [31:0] dstaddr_reg;
|
||||
wire [31:0] dstaddr_next;
|
||||
wire [31:0] dstaddr_mux;
|
||||
reg erx_access;
|
||||
reg erx_rdwr_access;
|
||||
reg erx_rr_access;
|
||||
reg [PW-1:0] erx_packet;
|
||||
wire [11:0] myid;
|
||||
wire [31:0] rx_addr;
|
||||
wire read_response;
|
||||
|
||||
//parsing inputs
|
||||
assign myid[11:0] = ID;
|
||||
assign rx_addr[31:0] = rx_packet[39:8];
|
||||
|
||||
//Address generator for bursting
|
||||
always @ (posedge clk)
|
||||
@ -50,15 +55,25 @@ module erx_protocol (/*AUTOARG*/
|
||||
assign dstaddr_next[31:0] = dstaddr_reg[31:0] + 4'b1000;
|
||||
|
||||
assign dstaddr_mux[31:0] = rx_burst ? dstaddr_next[31:0] :
|
||||
rx_packet[39:8];
|
||||
rx_addr[31:0];
|
||||
|
||||
//Pipeline stage
|
||||
|
||||
//Read response detector
|
||||
assign read_response = (rx_addr[31:20] == myid[11:0]) &
|
||||
(rx_addr[19:16] == `EGROUP_RR);
|
||||
|
||||
|
||||
//Pipeline stage and decode
|
||||
always @ (posedge clk)
|
||||
begin
|
||||
erx_access <= rx_access;
|
||||
//Write/read request
|
||||
erx_rdwr_access <= rx_access & ~read_response;
|
||||
//Read response
|
||||
erx_rr_access <= rx_access & read_response;
|
||||
//Common packet
|
||||
erx_packet[PW-1:0] <= {rx_packet[PW-1:40],
|
||||
dstaddr_mux[31:0],
|
||||
rx_packet[7:0]
|
||||
dstaddr_mux[31:0],
|
||||
rx_packet[7:0]
|
||||
};
|
||||
end
|
||||
|
||||
|
@ -3,8 +3,7 @@ module erx_remap (/*AUTOARG*/
|
||||
emesh_access_out, emesh_packet_out,
|
||||
// Inputs
|
||||
clk, reset, emesh_access_in, emesh_packet_in, remap_mode,
|
||||
remap_sel, remap_pattern, remap_base, remap_bypass, rx_rd_wait,
|
||||
rx_wr_wait
|
||||
remap_sel, remap_pattern, remap_base, rx_rd_wait, rx_wr_wait
|
||||
);
|
||||
|
||||
parameter AW = 32;
|
||||
@ -25,7 +24,6 @@ module erx_remap (/*AUTOARG*/
|
||||
input [11:0] remap_sel; //number of bits to remap
|
||||
input [11:0] remap_pattern; //static pattern to map to
|
||||
input [31:0] remap_base; //remap offset
|
||||
input remap_bypass; //dynamic bypass (read request | link match)
|
||||
|
||||
//Output to TX IO
|
||||
output emesh_access_out;
|
||||
@ -39,17 +37,21 @@ module erx_remap (/*AUTOARG*/
|
||||
wire [31:0] dynamic_remap;
|
||||
wire [31:0] remap_mux;
|
||||
wire write_in;
|
||||
wire read_in;
|
||||
wire [31:0] addr_in;
|
||||
wire [31:0] addr_out;
|
||||
wire remap_en;
|
||||
|
||||
reg emesh_access_out;
|
||||
reg [PW-1:0] emesh_packet_out;
|
||||
|
||||
//TODO:FIX!
|
||||
//TODO:FIX!??
|
||||
parameter[5:0] colid = ID[5:0];
|
||||
|
||||
//parsing packet
|
||||
assign addr_in[31:0] = emesh_packet_in[39:8];
|
||||
assign write_in = emesh_packet_in[1];
|
||||
assign read_in = ~emesh_packet_in[1];
|
||||
|
||||
//simple static remap
|
||||
assign static_remap[31:20] = (remap_sel[11:0] & remap_pattern[11:0]) |
|
||||
@ -58,31 +60,32 @@ module erx_remap (/*AUTOARG*/
|
||||
assign static_remap[19:0] = addr_in[19:0];
|
||||
|
||||
//more complex compresssed map
|
||||
assign dynamic_remap[31:0] = addr_in[31:0] //input
|
||||
- (colid << 20) //subtracing elink (start at 0)
|
||||
assign dynamic_remap[31:0] = addr_in[31:0] //input
|
||||
- (colid << 20) //subtracing elink (start at 0)
|
||||
+ remap_base[31:0] //adding back base
|
||||
- (addr_in[31:26]<<$clog2(colid));
|
||||
|
||||
|
||||
wire remap_en = ~(remap_mode[1:0]==2'b00);
|
||||
|
||||
assign remap_mux[31:0] = (remap_bypass | ~remap_en) ? addr_in[31:0] :
|
||||
(remap_mode[1:0]==2'b01) ? static_remap[31:0] :
|
||||
dynamic_remap[31:0];
|
||||
|
||||
//Static, dynamic, or no remap
|
||||
assign remap_mux[31:0] = (remap_mode[1:0]==2'b00) ? addr_in[31:0] :
|
||||
(remap_mode[1:0]==2'b01) ? static_remap[31:0] :
|
||||
dynamic_remap[31:0];
|
||||
|
||||
|
||||
//Access
|
||||
always @ (posedge clk)
|
||||
if (reset)
|
||||
begin
|
||||
emesh_access_out <= 'b0;
|
||||
end
|
||||
else if((write_in & ~rx_wr_wait) | (~write_in & ~rx_rd_wait))
|
||||
begin
|
||||
emesh_access_out <= emesh_access_in;
|
||||
emesh_packet_out[PW-1:0] <= {emesh_packet_in[103:40],
|
||||
remap_mux[31:0],
|
||||
emesh_packet_in[7:0]
|
||||
};
|
||||
end
|
||||
emesh_access_out <= 1'b0;
|
||||
else if((write_in & ~rx_wr_wait) | (read_in & ~rx_rd_wait))
|
||||
emesh_access_out <= emesh_access_in;
|
||||
|
||||
//Packet
|
||||
always @ (posedge clk)
|
||||
if((write_in & ~rx_wr_wait) | (read_in & ~rx_rd_wait))
|
||||
emesh_packet_out[PW-1:0] <= {emesh_packet_in[103:40],
|
||||
remap_mux[31:0],
|
||||
emesh_packet_in[7:0]
|
||||
};
|
||||
|
||||
endmodule // etx_mux
|
||||
|
||||
|
@ -149,13 +149,23 @@ module etx_arbiter (/*AUTOARG*/
|
||||
//Pipeline + stall
|
||||
assign write_in = etx_mux[1];
|
||||
|
||||
//access
|
||||
always @ (posedge clk)
|
||||
if (reset)
|
||||
begin
|
||||
etx_access <= 1'b0;
|
||||
etx_rr <= 1'b0;
|
||||
end
|
||||
else if (access_in & (write_in & ~etx_wr_wait) | (~write_in & ~etx_rd_wait))
|
||||
begin
|
||||
etx_access <= access_in;
|
||||
etx_rr <= txrr_grant;
|
||||
end
|
||||
|
||||
//packet
|
||||
always @ (posedge clk)
|
||||
if (access_in & (write_in & ~etx_wr_wait) | (~write_in & ~etx_rd_wait))
|
||||
begin
|
||||
etx_access <= access_in;
|
||||
etx_packet[PW-1:0] <= etx_mux[PW-1:0];
|
||||
etx_rr <= txrr_grant;
|
||||
end
|
||||
etx_packet[PW-1:0] <= etx_mux[PW-1:0];
|
||||
|
||||
endmodule // etx_arbiter
|
||||
// Local Variables:
|
||||
@ -164,8 +174,6 @@ endmodule // etx_arbiter
|
||||
|
||||
|
||||
/*
|
||||
File: etx_arbiter.v
|
||||
|
||||
Copyright (C) 2015 Adapteva, Inc.
|
||||
Contributed by Andreas Olofsson <andreas@adapteva.com>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user