Commit b07f70ada3aed7476189bc54d19d422c5f52e9cd
1 parent
bec01f1540
Exists in
master
and in
5 other branches
Fixed a Verilog non-compliant bug.
Showing 2 changed files with 22 additions and 16 deletions Inline Diff
src/core_memory_arbiter.v
View file @
b07f70a
/* core_memory_arbiter.v | 1 | 1 | /* core_memory_arbiter.v | |
* Author: Zinsser Zhang | 2 | 2 | * Author: Zinsser Zhang | |
* Last Revision: 04/29/2017 | 3 | 3 | * Last Revision: 04/29/2017 | |
* Based on Pravin P. Prabhu's memory_arbiter.v | 4 | 4 | * Based on Pravin P. Prabhu's memory_arbiter.v | |
* Abstract: | 5 | 5 | * Abstract: | |
* Provides arbitration between i_cache and d_cache for request to memory. | 6 | 6 | * Provides arbitration between i_cache and d_cache for request to memory. | |
* All addresses used in this scope are word addresses (32-bit/4-byte aligned) | 7 | 7 | * All addresses used in this scope are word addresses (32-bit/4-byte aligned) | |
* Will service sources in order of priority, which is: | 8 | 8 | * Will service sources in order of priority, which is: | |
* (high) | 9 | 9 | * (high) | |
* imem | 10 | 10 | * imem | |
* dmem | 11 | 11 | * dmem | |
* (low) | 12 | 12 | * (low) | |
*/ | 13 | 13 | */ | |
module core_memory_arbiter #( parameter DATA_WIDTH=32, | 14 | 14 | module core_memory_arbiter #( parameter DATA_WIDTH=32, | |
parameter ADDRESS_WIDTH=21 | 15 | 15 | parameter ADDRESS_WIDTH=21 | |
) | 16 | 16 | ) | |
( | 17 | 17 | ( | |
// General | 18 | 18 | // General | |
input i_Clk, | 19 | 19 | input i_Clk, | |
input i_Reset_n, | 20 | 20 | input i_Reset_n, | |
21 | 21 | |||
// Requests to/from IMEM - Assume we always read | 22 | 22 | // Requests to/from IMEM - Assume we always read | |
input i_IMEM_Valid, // If IMEM request is valid | 23 | 23 | input i_IMEM_Valid, // If IMEM request is valid | |
input [ADDRESS_WIDTH-1:0] i_IMEM_Address, // IMEM request addr. | 24 | 24 | input [ADDRESS_WIDTH-1:0] i_IMEM_Address, // IMEM request addr. | |
output reg o_IMEM_Valid, | 25 | 25 | output reg o_IMEM_Valid, | |
output reg o_IMEM_Last, | 26 | 26 | output reg o_IMEM_Last, | |
output reg [DATA_WIDTH-1:0] o_IMEM_Data, | 27 | 27 | output reg [DATA_WIDTH-1:0] o_IMEM_Data, | |
28 | 28 | |||
// Requests to/from DMEM | 29 | 29 | // Requests to/from DMEM | |
input i_DMEM_Valid, | 30 | 30 | input i_DMEM_Valid, | |
input i_DMEM_Read_Write_n, | 31 | 31 | input i_DMEM_Read_Write_n, | |
input [ADDRESS_WIDTH-1:0] i_DMEM_Address, | 32 | 32 | input [ADDRESS_WIDTH-1:0] i_DMEM_Address, | |
input [DATA_WIDTH-1:0] i_DMEM_Data, | 33 | 33 | input [DATA_WIDTH-1:0] i_DMEM_Data, | |
output reg o_DMEM_Valid, | 34 | 34 | output reg o_DMEM_Valid, | |
output reg o_DMEM_Data_Read, | 35 | 35 | output reg o_DMEM_Data_Read, | |
output reg o_DMEM_Last, | 36 | 36 | output reg o_DMEM_Last, | |
output reg [DATA_WIDTH-1:0] o_DMEM_Data, | 37 | 37 | output reg [DATA_WIDTH-1:0] o_DMEM_Data, | |
38 | 38 | |||
// Interface to outside of the core | 39 | 39 | // Interface to outside of the core | |
output reg o_MEM_Valid, | 40 | 40 | output reg o_MEM_Valid, | |
output reg [ADDRESS_WIDTH-1:0] o_MEM_Address, | 41 | 41 | output reg [ADDRESS_WIDTH-1:0] o_MEM_Address, | |
output reg o_MEM_Read_Write_n, | 42 | 42 | output reg o_MEM_Read_Write_n, | |
43 | 43 | |||
// Write data interface | 44 | 44 | // Write data interface | |
output reg [DATA_WIDTH-1:0] o_MEM_Data, | 45 | 45 | output reg [DATA_WIDTH-1:0] o_MEM_Data, | |
input i_MEM_Data_Read, | 46 | 46 | input i_MEM_Data_Read, | |
47 | 47 | |||
// Read data interface | 48 | 48 | // Read data interface | |
input [DATA_WIDTH-1:0] i_MEM_Data, | 49 | 49 | input [DATA_WIDTH-1:0] i_MEM_Data, | |
input i_MEM_Valid, | 50 | 50 | input i_MEM_Valid, | |
51 | 51 | |||
input i_MEM_Last // If we're on the last piece of the transaction | 52 | 52 | input i_MEM_Last // If we're on the last piece of the transaction | |
); | 53 | 53 | ); | |
54 | 54 | |||
// Consts | 55 | 55 | // Consts | |
localparam TRUE = 1'b1; | 56 | 56 | localparam TRUE = 1'b1; | |
localparam FALSE = 1'b0; | 57 | 57 | localparam FALSE = 1'b0; | |
localparam READ = 1'b1; | 58 | 58 | localparam READ = 1'b1; | |
localparam WRITE = 1'b0; | 59 | 59 | localparam WRITE = 1'b0; | |
60 | 60 | |||
// State of the arbiter | 61 | 61 | // State of the arbiter | |
localparam STATE_READY = 4'd0; | 62 | 62 | localparam STATE_READY = 4'd0; | |
localparam STATE_SERVICING_IMEM = 4'd1; | 63 | 63 | localparam STATE_SERVICING_IMEM = 4'd1; | |
localparam STATE_SERVICING_DMEM = 4'd2; | 64 | 64 | localparam STATE_SERVICING_DMEM = 4'd2; | |
65 | 65 | |||
reg [3:0] State; | 66 | 66 | reg [3:0] State; | |
reg [3:0] NextState; | 67 | 67 | reg [3:0] NextState; | |
68 | 68 | |||
always @(*) | 69 | 69 | always @(*) | |
begin | 70 | 70 | begin | |
NextState <= State; | 71 | 71 | NextState <= State; | |
case(State) | 72 | 72 | case(State) | |
STATE_READY: | 73 | 73 | STATE_READY: | |
begin | 74 | 74 | begin | |
if (i_IMEM_Valid) | 75 | 75 | if (i_IMEM_Valid) | |
NextState <= STATE_SERVICING_IMEM; | 76 | 76 | NextState <= STATE_SERVICING_IMEM; | |
else if (i_DMEM_Valid) | 77 | 77 | else if (i_DMEM_Valid) | |
NextState <= STATE_SERVICING_DMEM; | 78 | 78 | NextState <= STATE_SERVICING_DMEM; | |
end | 79 | 79 | end | |
80 | 80 | |||
STATE_SERVICING_IMEM: | 81 | 81 | STATE_SERVICING_IMEM: | |
begin | 82 | 82 | begin | |
if (i_MEM_Last) | 83 | 83 | if (i_MEM_Last) | |
NextState <= STATE_READY; | 84 | 84 | NextState <= STATE_READY; | |
end | 85 | 85 | end | |
86 | 86 | |||
STATE_SERVICING_DMEM: | 87 | 87 | STATE_SERVICING_DMEM: | |
begin | 88 | 88 | begin | |
if (i_MEM_Last) | 89 | 89 | if (i_MEM_Last) | |
NextState <= STATE_READY; | 90 | 90 | NextState <= STATE_READY; | |
end | 91 | 91 | end | |
endcase | 92 | 92 | endcase | |
93 | end | |||
93 | 94 | |||
95 | always @(*) | |||
96 | begin | |||
o_IMEM_Valid <= FALSE; | 94 | 97 | o_IMEM_Valid <= FALSE; | |
o_IMEM_Last <= FALSE; | 95 | 98 | o_IMEM_Last <= FALSE; | |
o_IMEM_Data <= {32{1'bx}}; | 96 | 99 | o_IMEM_Data <= {32{1'bx}}; | |
o_DMEM_Valid <= FALSE; | 97 | 100 | o_DMEM_Valid <= FALSE; | |
o_DMEM_Data_Read <= FALSE; | 98 | 101 | o_DMEM_Data_Read <= FALSE; | |
o_DMEM_Last <= FALSE; | 99 | 102 | o_DMEM_Last <= FALSE; | |
o_DMEM_Data <= {32{1'bx}}; | 100 | 103 | o_DMEM_Data <= {32{1'bx}}; | |
o_MEM_Valid <= FALSE; | 101 | 104 | o_MEM_Valid <= FALSE; | |
o_MEM_Address <= {ADDRESS_WIDTH{1'bx}}; | 102 | 105 | o_MEM_Address <= {ADDRESS_WIDTH{1'bx}}; | |
o_MEM_Read_Write_n <= READ; | 103 | 106 | o_MEM_Read_Write_n <= READ; | |
o_MEM_Data <= {32{1'bx}}; | 104 | 107 | o_MEM_Data <= {32{1'bx}}; | |
105 | 108 | |||
if (State == STATE_SERVICING_IMEM || NextState == STATE_SERVICING_IMEM) | 106 | 109 | if (State == STATE_SERVICING_IMEM || NextState == STATE_SERVICING_IMEM) | |
begin | 107 | 110 | begin | |
o_MEM_Valid <= TRUE; | 108 | 111 | o_MEM_Valid <= TRUE; | |
o_MEM_Address <= i_IMEM_Address; | 109 | 112 | o_MEM_Address <= i_IMEM_Address; | |
o_MEM_Read_Write_n <= READ; | 110 | 113 | o_MEM_Read_Write_n <= READ; | |
o_IMEM_Valid <= i_MEM_Valid; | 111 | 114 | o_IMEM_Valid <= i_MEM_Valid; | |
o_IMEM_Last <= i_MEM_Last; | 112 | 115 | o_IMEM_Last <= i_MEM_Last; | |
o_IMEM_Data <= i_MEM_Data; | 113 | 116 | o_IMEM_Data <= i_MEM_Data; | |
end | 114 | 117 | end | |
else if (State == STATE_SERVICING_DMEM || NextState == STATE_SERVICING_DMEM) | 115 | 118 | else if (State == STATE_SERVICING_DMEM || NextState == STATE_SERVICING_DMEM) | |
begin | 116 | 119 | begin | |
o_MEM_Valid <= TRUE; | 117 | 120 | o_MEM_Valid <= TRUE; | |
o_MEM_Address <= i_DMEM_Address; | 118 | 121 | o_MEM_Address <= i_DMEM_Address; | |
o_MEM_Read_Write_n <= i_DMEM_Read_Write_n; | 119 | 122 | o_MEM_Read_Write_n <= i_DMEM_Read_Write_n; | |
o_MEM_Data <= i_DMEM_Data; | 120 | 123 | o_MEM_Data <= i_DMEM_Data; | |
o_DMEM_Valid <= i_MEM_Valid; | 121 | 124 | o_DMEM_Valid <= i_MEM_Valid; | |
o_DMEM_Data_Read <= i_MEM_Data_Read; | 122 | 125 | o_DMEM_Data_Read <= i_MEM_Data_Read; | |
o_DMEM_Last <= i_MEM_Last; | 123 | 126 | o_DMEM_Last <= i_MEM_Last; | |
o_DMEM_Data <= i_MEM_Data; | 124 | 127 | o_DMEM_Data <= i_MEM_Data; | |
end | 125 | 128 | end | |
end | 126 | 129 | end | |
127 | 130 | |||
// State driver | 128 | 131 | // State driver | |
always @(posedge i_Clk or negedge i_Reset_n) | 129 | 132 | always @(posedge i_Clk or negedge i_Reset_n) | |
begin | 130 | 133 | begin | |
if( !i_Reset_n ) | 131 | 134 | if( !i_Reset_n ) | |
// Defaults | 132 | 135 | // Defaults | |
State <= STATE_READY; | 133 | 136 | State <= STATE_READY; | |
else | 134 | 137 | else | |
State <= NextState; | 135 | 138 | State <= NextState; | |
end | 136 | 139 | end | |
137 | 140 |
src/memory_arbiter.v
View file @
b07f70a
/* memory_arbiter.v | 1 | 1 | /* memory_arbiter.v | |
* Author: Pravin P. Prabhu, Zinsser Zhang | 2 | 2 | * Author: Pravin P. Prabhu, Zinsser Zhang | |
* Last Revision: 04/29/2017 | 3 | 3 | * Last Revision: 04/29/2017 | |
* Abstract: | 4 | 4 | * Abstract: | |
* Provides arbitration amongst sources that all wish to request from main | 5 | 5 | * Provides arbitration amongst sources that all wish to request from main | |
* memory. Will service sources in order of priority, which is: | 6 | 6 | * memory. Will service sources in order of priority, which is: | |
* (high) | 7 | 7 | * (high) | |
* flashloader | 8 | 8 | * flashloader | |
* CORE | 9 | 9 | * CORE | |
* (low) | 10 | 10 | * (low) | |
*/ | 11 | 11 | */ | |
module memory_arbiter #( parameter DATA_WIDTH=32, | 12 | 12 | module memory_arbiter #( parameter DATA_WIDTH=32, | |
parameter ADDRESS_WIDTH=22, | 13 | 13 | parameter ADDRESS_WIDTH=22, | |
parameter CORE_ADDRESS_WIDTH=21 | 14 | 14 | parameter CORE_ADDRESS_WIDTH=21 | |
) | 15 | 15 | ) | |
( | 16 | 16 | ( | |
// General | 17 | 17 | // General | |
input i_Clk, | 18 | 18 | input i_Clk, | |
input i_Reset_n, | 19 | 19 | input i_Reset_n, | |
20 | 20 | |||
// Requests to/from CORE | 21 | 21 | // Requests to/from CORE | |
input i_CORE_Valid, | 22 | 22 | input i_CORE_Valid, | |
input i_CORE_Read_Write_n, | 23 | 23 | input i_CORE_Read_Write_n, | |
input [CORE_ADDRESS_WIDTH-1:0] i_CORE_Address, | 24 | 24 | input [CORE_ADDRESS_WIDTH-1:0] i_CORE_Address, | |
input [DATA_WIDTH-1:0] i_CORE_Data, | 25 | 25 | input [DATA_WIDTH-1:0] i_CORE_Data, | |
output reg o_CORE_Valid, | 26 | 26 | output reg o_CORE_Valid, | |
output reg o_CORE_Data_Read, | 27 | 27 | output reg o_CORE_Data_Read, | |
output reg o_CORE_Last, | 28 | 28 | output reg o_CORE_Last, | |
output reg [DATA_WIDTH-1:0] o_CORE_Data, | 29 | 29 | output reg [DATA_WIDTH-1:0] o_CORE_Data, | |
30 | 30 | |||
// Requests to/from FLASH - Assume we always write | 31 | 31 | // Requests to/from FLASH - Assume we always write | |
input i_Flash_Valid, | 32 | 32 | input i_Flash_Valid, | |
input [DATA_WIDTH-1:0] i_Flash_Data, | 33 | 33 | input [DATA_WIDTH-1:0] i_Flash_Data, | |
input [ADDRESS_WIDTH-1:0] i_Flash_Address, | 34 | 34 | input [ADDRESS_WIDTH-1:0] i_Flash_Address, | |
output reg o_Flash_Data_Read, | 35 | 35 | output reg o_Flash_Data_Read, | |
output reg o_Flash_Last, | 36 | 36 | output reg o_Flash_Last, | |
37 | 37 | |||
// Interface with SDRAM Controller | 38 | 38 | // Interface with SDRAM Controller | |
output reg o_MEM_Valid, | 39 | 39 | output reg o_MEM_Valid, | |
output reg [ADDRESS_WIDTH-1:0] o_MEM_Address, | 40 | 40 | output reg [ADDRESS_WIDTH-1:0] o_MEM_Address, | |
output reg o_MEM_Read_Write_n, | 41 | 41 | output reg o_MEM_Read_Write_n, | |
42 | 42 | |||
// Write data interface | 43 | 43 | // Write data interface | |
output reg [DATA_WIDTH-1:0] o_MEM_Data, | 44 | 44 | output reg [DATA_WIDTH-1:0] o_MEM_Data, | |
input i_MEM_Data_Read, | 45 | 45 | input i_MEM_Data_Read, | |
46 | 46 | |||
// Read data interface | 47 | 47 | // Read data interface | |
input [DATA_WIDTH-1:0] i_MEM_Data, | 48 | 48 | input [DATA_WIDTH-1:0] i_MEM_Data, | |
input i_MEM_Data_Valid, | 49 | 49 | input i_MEM_Data_Valid, | |
50 | 50 | |||
input i_MEM_Last // If we're on the last piece of the transaction | 51 | 51 | input i_MEM_Last // If we're on the last piece of the transaction | |
); | 52 | 52 | ); | |
53 | 53 | |||
// Consts | 54 | 54 | // Consts | |
localparam TRUE = 1'b1; | 55 | 55 | localparam TRUE = 1'b1; | |
localparam FALSE = 1'b0; | 56 | 56 | localparam FALSE = 1'b0; | |
localparam READ = 1'b1; | 57 | 57 | localparam READ = 1'b1; | |
localparam WRITE = 1'b0; | 58 | 58 | localparam WRITE = 1'b0; | |
59 | 59 | |||
// State of the arbiter | 60 | 60 | // State of the arbiter | |
localparam STATE_READY = 4'd0; | 61 | 61 | localparam STATE_READY = 4'd0; | |
localparam STATE_SERVICING_FLASH = 4'd1; | 62 | 62 | localparam STATE_SERVICING_FLASH = 4'd1; | |
localparam STATE_SERVICING_CORE = 4'd2; | 63 | 63 | localparam STATE_SERVICING_CORE = 4'd2; | |
64 | 64 | |||
reg [3:0] State; | 65 | 65 | reg [3:0] State; | |
reg [3:0] NextState; | 66 | 66 | reg [3:0] NextState; | |
67 | 67 | |||
always @(*) | 68 | 68 | always @(*) | |
begin | 69 | 69 | begin | |
NextState <= State; | 70 | 70 | NextState <= State; | |
case(State) | 71 | 71 | case(State) | |
STATE_READY: | 72 | 72 | STATE_READY: | |
begin | 73 | 73 | begin | |
if (i_Flash_Valid) | 74 | 74 | if (i_Flash_Valid) | |
NextState <= STATE_SERVICING_FLASH; | 75 | 75 | NextState <= STATE_SERVICING_FLASH; | |
else if (i_CORE_Valid) | 76 | 76 | else if (i_CORE_Valid) | |
NextState <= STATE_SERVICING_CORE; | 77 | 77 | NextState <= STATE_SERVICING_CORE; | |
end | 78 | 78 | end | |
79 | 79 | |||
STATE_SERVICING_FLASH: | 80 | 80 | STATE_SERVICING_FLASH: | |
begin | 81 | 81 | begin | |
if (i_MEM_Last) | 82 | 82 | if (i_MEM_Last) | |
NextState <= STATE_READY; | 83 | 83 | NextState <= STATE_READY; | |
end | 84 | 84 | end | |
85 | 85 | |||
STATE_SERVICING_CORE: | 86 | 86 | STATE_SERVICING_CORE: | |
begin | 87 | 87 | begin | |
if (i_MEM_Last) | 88 | 88 | if (i_MEM_Last) | |
NextState <= STATE_READY; | 89 | 89 | NextState <= STATE_READY; | |
end | 90 | 90 | end | |
endcase | 91 | 91 | endcase | |
92 | end | |||
92 | 93 | |||
94 | always @(*) | |||
95 | begin | |||
o_CORE_Valid <= FALSE; | 93 | 96 | o_CORE_Valid <= FALSE; | |
o_CORE_Data_Read <= FALSE; | 94 | 97 | o_CORE_Data_Read <= FALSE; | |
o_CORE_Last <= FALSE; | 95 | 98 | o_CORE_Last <= FALSE; | |
o_CORE_Data <= {32{1'bx}}; | 96 | 99 | o_CORE_Data <= {32{1'bx}}; | |
o_Flash_Data_Read <= FALSE; | 97 | 100 | o_Flash_Data_Read <= FALSE; | |
o_Flash_Last <= FALSE; | 98 | 101 | o_Flash_Last <= FALSE; | |
o_MEM_Valid <= FALSE; | 99 | 102 | o_MEM_Valid <= FALSE; | |
o_MEM_Address <= {ADDRESS_WIDTH{1'bx}}; | 100 | 103 | o_MEM_Address <= {ADDRESS_WIDTH{1'bx}}; | |
o_MEM_Read_Write_n <= READ; | 101 | 104 | o_MEM_Read_Write_n <= READ; | |
o_MEM_Data <= {32{1'bx}}; | 102 | 105 | o_MEM_Data <= {32{1'bx}}; | |
103 | 106 | |||
if (State == STATE_SERVICING_FLASH || NextState == STATE_SERVICING_FLASH) | 104 | 107 | if (State == STATE_SERVICING_FLASH || NextState == STATE_SERVICING_FLASH) | |
begin | 105 | 108 | begin | |
// Servicing flash: Bridge flash I/O | 106 | 109 | // Servicing flash: Bridge flash I/O | |
o_MEM_Valid <= TRUE; | 107 | 110 | o_MEM_Valid <= TRUE; | |
o_MEM_Address <= i_Flash_Address; | 108 | 111 | o_MEM_Address <= i_Flash_Address; | |
o_MEM_Read_Write_n <= WRITE; | 109 | 112 | o_MEM_Read_Write_n <= WRITE; | |
o_MEM_Data <= i_Flash_Data; | 110 | 113 | o_MEM_Data <= i_Flash_Data; | |
o_Flash_Data_Read <= i_MEM_Data_Read; | 111 | 114 | o_Flash_Data_Read <= i_MEM_Data_Read; | |
o_Flash_Last <= i_MEM_Last; | 112 | 115 | o_Flash_Last <= i_MEM_Last; | |
end | 113 | 116 | end | |
else if (State == STATE_SERVICING_CORE || NextState == STATE_SERVICING_CORE) | 114 | 117 | else if (State == STATE_SERVICING_CORE || NextState == STATE_SERVICING_CORE) | |
begin | 115 | 118 | begin | |
o_MEM_Valid <= TRUE; | 116 | 119 | o_MEM_Valid <= TRUE; | |
o_MEM_Address <= {i_CORE_Address, 1'b0}; | 117 | 120 | o_MEM_Address <= {i_CORE_Address, 1'b0}; | |
o_MEM_Read_Write_n <= i_CORE_Read_Write_n; | 118 | 121 | o_MEM_Read_Write_n <= i_CORE_Read_Write_n; | |
o_MEM_Data <= i_CORE_Data; | 119 | 122 | o_MEM_Data <= i_CORE_Data; | |
o_CORE_Valid <= i_MEM_Data_Valid; | 120 | 123 | o_CORE_Valid <= i_MEM_Data_Valid; | |
o_CORE_Data_Read <= i_MEM_Data_Read; | 121 | 124 | o_CORE_Data_Read <= i_MEM_Data_Read; |