@@ -45,45 +45,58 @@ riscv_out_t riscv_name(
4545
4646 // Instead of a counter for which stage is active
4747 // one hot bit is easier to work with (especially come time for pipelining)
48- static uint1_t stage_valid [N_CYCLES ] = {[0 ]= 1 }; // Starts in stage_valid [0]
49- uint1_t next_stage_valid [N_CYCLES ]; // Update static reg at end of func
48+ static uint1_t state [N_CYCLES ] = {[0 ]= 1 }; // Starts in state [0]
49+ uint1_t next_state [N_CYCLES ] = state ; // Update static reg at end of func
5050
5151 // CPU registers (outside of reg file)
5252 static uint32_t pc = 0 ;
5353 o .pc = pc ; // debug
5454 // Wires/non-static local variables from original single cycle design
5555 // are likely to be shared/stored from cycle to cycle now
5656 // so just declare all (non-FEEDBACK) local variables static registers too
57- static uint32_t pc_plus4 ;
58- static riscv_imem_ram_out_t imem_out ;
59- static decoded_t decoded ;
60- static reg_file_out_t reg_file_out ;
61- static execute_t exe ;
62- static uint1_t mem_wr_byte_ens [4 ];
63- static uint1_t mem_rd_byte_ens [4 ];
64- static uint32_t mem_addr ;
65- static uint32_t mem_wr_data ;
66- static riscv_dmem_out_t dmem_out ;
57+ static uint32_t pc_plus4_reg ;
58+ static riscv_imem_ram_out_t imem_out_reg ;
59+ static decoded_t decoded_reg ;
60+ static reg_file_out_t reg_file_out_reg ;
61+ static execute_t exe_reg ;
62+ static uint1_t mem_wr_byte_ens_reg [4 ];
63+ static uint1_t mem_rd_byte_ens_reg [4 ];
64+ static uint32_t mem_addr_reg ;
65+ static uint32_t mem_wr_data_reg ;
66+ static riscv_dmem_out_t dmem_out_reg ;
67+ // But still have non-static wires version of registers too
68+ // to help avoid/resolve unintentional passing of data between stages
69+ // in the same cycle (like single cycle cpu did)
70+ uint32_t pc_plus4 = pc_plus4_reg ;
71+ riscv_imem_ram_out_t imem_out = imem_out_reg ;
72+ decoded_t decoded = decoded_reg ;
73+ reg_file_out_t reg_file_out = reg_file_out_reg ;
74+ execute_t exe = exe_reg ;
75+ uint1_t mem_wr_byte_ens [4 ] = mem_wr_byte_ens_reg ;
76+ uint1_t mem_rd_byte_ens [4 ] = mem_rd_byte_ens_reg ;
77+ uint32_t mem_addr = mem_addr_reg ;
78+ uint32_t mem_wr_data = mem_wr_data_reg ;
79+ riscv_dmem_out_t dmem_out = dmem_out_reg ;
6780
6881 // Cycle 0: PC
69- if (stage_valid [0 ]){
82+ if (state [0 ]){
7083 printf ("PC in Cycle/Stage 0\n" );
7184 // Program counter is input to IMEM
7285 pc_plus4 = pc + 4 ;
7386 printf ("PC = 0x%X\n" , pc );
7487 // Next state/cycle (potentially redundant)
75- next_stage_valid = stage_valid ;
76- ARRAY_1ROT_UP (uint1_t , next_stage_valid , N_CYCLES )
88+ next_state = state ;
89+ ARRAY_1ROT_UP (uint1_t , next_state , N_CYCLES )
7790 }
7891
7992 // Boundary shared between cycle0 and cycle1
80- if (stage_valid [0 ]|stage_valid [1 ]){
93+ if (state [0 ]|state [1 ]){
8194 // Instruction memory
8295 imem_out = riscv_imem_ram (pc >>2 , 1 );
8396 }
8497
8598 // Cycle1: Decode
86- if (stage_valid [1 ]){
99+ if (state [1 ]){
87100 printf ("Decode in Cycle/Stage 1\n" );
88101 // Decode the instruction to control signals
89102 printf ("Instruction: 0x%X\n" , imem_out .rd_data1 );
@@ -96,8 +109,8 @@ riscv_out_t riscv_name(
96109 }
97110 o .unknown_op = decoded .unknown_op ; // debug
98111 // Next state/cycle (potentially redundant)
99- next_stage_valid = stage_valid ;
100- ARRAY_1ROT_UP (uint1_t , next_stage_valid , N_CYCLES )
112+ next_state = state ;
113+ ARRAY_1ROT_UP (uint1_t , next_state , N_CYCLES )
101114 }
102115
103116 // Cycle1+2: Register file reads and writes
@@ -111,7 +124,7 @@ riscv_out_t riscv_name(
111124 #pragma FEEDBACK reg_wr_addr
112125 #pragma FEEDBACK reg_wr_data
113126 #pragma FEEDBACK reg_wr_en
114- if (stage_valid [1 ]|stage_valid [2 ]){
127+ if (state [1 ]|state [2 ]){
115128 reg_file_out = reg_file (
116129 decoded .src1 , // First read port address
117130 decoded .src2 , // Second read port address
@@ -120,31 +133,31 @@ riscv_out_t riscv_name(
120133 reg_wr_en // Write enable
121134 );
122135 // Next state/cycle (potentially redundant)
123- next_stage_valid = stage_valid ;
124- ARRAY_1ROT_UP (uint1_t , next_stage_valid , N_CYCLES )
136+ next_state = state ;
137+ ARRAY_1ROT_UP (uint1_t , next_state , N_CYCLES )
125138 }
126139
127140 // Cycle1: Execute
128- if (stage_valid [1 ]){
141+ if (state [1 ]){
129142 printf ("Execute in Cycle/Stage 1\n" );
130143 exe = execute (
131- pc , pc_plus4 ,
144+ pc , pc_plus4_reg ,
132145 decoded ,
133146 reg_file_out .rd_data1 , reg_file_out .rd_data2
134147 );
135148 // Next state/cycle (potentially redundant)
136- next_stage_valid = stage_valid ;
137- ARRAY_1ROT_UP (uint1_t , next_stage_valid , N_CYCLES )
149+ next_state = state ;
150+ ARRAY_1ROT_UP (uint1_t , next_state , N_CYCLES )
138151 }
139152
140153 // Boundary shared between cycle1 and cycle2
141154 // Data Memory inputs in stage1
142155 // Default no writes or reads
143156 ARRAY_SET (mem_wr_byte_ens , 0 , 4 )
144157 ARRAY_SET (mem_rd_byte_ens , 0 , 4 )
145- uint32_t mem_addr = exe .result ; // addr always from execute module, not always used
146- uint32_t mem_wr_data = reg_file_out .rd_data2 ;
147- if (stage_valid [1 ]){
158+ mem_addr = exe .result ; // addr always from execute module, not always used
159+ mem_wr_data = reg_file_out .rd_data2 ;
160+ if (state [1 ]){
148161 // Only write or read en during first cycle of two cycle read
149162 mem_wr_byte_ens = decoded .mem_wr_byte_ens ;
150163 mem_rd_byte_ens = decoded .mem_rd_byte_ens ;
@@ -170,10 +183,10 @@ riscv_out_t riscv_name(
170183 o .mem_map_outputs = dmem_out .mem_map_outputs ;
171184 #endif
172185 // Data memory outputs in stage2
173- if (stage_valid [2 ]){
186+ if (state [2 ]){
174187 // Read output available from dmem_out in second cycle of two cycle read
175- if (decoded .mem_rd_byte_ens [0 ]){
176- printf ("Read Mem[0x%X] = %d\n" , mem_addr , dmem_out .rd_data );
188+ if (decoded_reg .mem_rd_byte_ens [0 ]){
189+ printf ("Read Mem[0x%X] = %d\n" , mem_addr_reg , dmem_out .rd_data );
177190 }
178191 }
179192
@@ -182,27 +195,37 @@ riscv_out_t riscv_name(
182195 reg_wr_en = 0 ; // default no writes
183196 reg_wr_addr = 0 ;
184197 reg_wr_data = 0 ;
185- if (stage_valid [2 ]){
198+ if (state [2 ]){
186199 printf ("Write Back + Next PC in Cycle/Stage 2\n" );
187200 // Reg file write back, drive inputs (FEEDBACK)
188- reg_wr_en = decoded .reg_wr ;
189- reg_wr_addr = decoded .dest ;
201+ reg_wr_en = decoded_reg .reg_wr ;
202+ reg_wr_addr = decoded_reg .dest ;
190203 // Determine reg data to write back (sign extend etc)
191204 reg_wr_data = select_reg_wr_data (
192- decoded ,
193- exe ,
205+ decoded_reg ,
206+ exe_reg ,
194207 dmem_out .rd_data ,
195- pc_plus4
208+ pc_plus4_reg
196209 );
197210 // Branch/Increment PC
198- pc = select_next_pc (decoded , exe , pc_plus4 );
211+ pc = select_next_pc (decoded_reg , exe_reg , pc_plus4_reg );
199212 // Next state/cycle (potentially redundant)
200- next_stage_valid = stage_valid ;
201- ARRAY_1ROT_UP (uint1_t , next_stage_valid , N_CYCLES )
213+ next_state = state ;
214+ ARRAY_1ROT_UP (uint1_t , next_state , N_CYCLES )
202215 }
203216
204217 // Reg update
205- stage_valid = next_stage_valid ;
218+ state = next_state ;
219+ pc_plus4_reg = pc_plus4 ;
220+ imem_out_reg = imem_out ;
221+ decoded_reg = decoded ;
222+ reg_file_out_reg = reg_file_out ;
223+ exe_reg = exe ;
224+ mem_wr_byte_ens_reg = mem_wr_byte_ens ;
225+ mem_rd_byte_ens_reg = mem_rd_byte_ens ;
226+ mem_addr_reg = mem_addr ;
227+ mem_wr_data_reg = mem_wr_data ;
228+ dmem_out_reg = dmem_out ;
206229
207230 return o ;
208231}
0 commit comments