Designing this is not a part of the curriculum for me and my friend right now. We are just experimenting with Verilog after studying combinational and sequential circuits.
Code used:
ALU.v
module ALU(input enable, input [0:1] op, input [0:3] n1, input [0:3] n2, output reg [3:0] out);
always @ (enable) begin
if (enable) begin
case(op)
2'b00: out = n1 + n2;
2'b01: out = n1 - n2;
2'b10: out = n1 * n2;
2'b11: out = n1 / n2;
endcase
end
end
endmodule
Processor.v
module Processor(input [0:7] sig);
reg [4:0] registers[0:3];
reg enable;
ALU ALU1(.enable(enable),.op(sig[2:3]),.n1(registers[3]),.n2(registers[0]),.out(registers[0]));
always @ (sig) begin
enable = 1'b0;
case(sig[0:1])
2'b00: registers[0] = registers[sig[2:3]];
2'b01: registers[sig[2:3]] = registers[0];
2'b10: registers[sig[2:3]] = sig[4:7];
2'b11: registers[3] = registers[0];
registers[0] = registers[sig[4:5]];
enable = 1'b1;
endcase
end
endmodule
testProcessor.v
module test_Processor;
reg [0:7] sig;
Processor uut(.sig(sig));
initial begin
$dumpfile("Processor.vcd");
$dumpvars("0,test_Processor");
sig = 8'b10010011;#10;
sig = 8'b10100001;#10;
sig = 8'b00010000;#10;
sig = 8'b11001000;#10;
end
endmodule
We got the following errors:
Processor.v:12: syntax error
Processor.v:12: error: Malformed statement
Processor.v:12: error: Incomprehensible case expression.
Processor.v:13: syntax error
test_Processor.v:2: error: Malformed statement
test_Processor.v:2: error: Incomprehensible case expression.
test_Processor.v:3: syntax error
I give up.
I'm not very good at Verilog, but I can see that vectors' size mismatches, leading to those errors.
So, we always get stuck in this endless cycle of
Write code -- Fail -- Debug -- Write code.
So, far we haven't got this working, where will this stop?
We use iverilog
on Linux.
One more question that we had was, can we get a 64 bit RISC processor to work on Spartan 6 FPGA, we were told that it was impossible from our professor (he's a kind guy)? Our professor told us that we would have to upgrade to a higher board to do that.
What fundamentally limits the ability of an FPGA to simulate such a processor?
2 Answers 2
For this part of the question:
What fundamentally limits the ability of an FPGA to simulate such a processor?
It depends upon the resource utilisation of the processor.
Since the question mentions a Spartan 6, the Xilinx MicroBlaze Architecture Features shows that MicroBlaze version v11.0 is the first version to support 64-bit mode. The Spartan 7 Devices section of the document shows a 64-bit MicroBlaze is supported and has table Device Utilization - Spartan 7 FPGAs (XC7S25 csga225-2) showing for different configurations:
- The number of LUTs used
- The number of FFs used
- The number of BRAMs (36k) used
- The maximum clock frequency
The above document is for the Vivado design suite, which doesn't support the Spartan-6 series devices.
Spartan-6 is supported by the previous ISE tool. The MicroBlaze Processor Reference Guide for Embedded Development Kit EDK 14.7 which is part of ISE 14.7 shows MicroBlaze v8.50 is the latest version of the processor supported by ISE and therefore a Spartan-6 FPGA. The fixed feature set of the MicroBlaze supported by ISE is:
- Thirty-two 32-bit general purpose registers
- 32-bit instruction word with three operands and two addressing modes
- 32-bit address bus
Therefore, a Spartan-6 doesn't support a 64-bit MicroBlaze processor.
While this doesn't answer all of the question, hopefully if provides some guidance on further research.
To address some of the Verilog issues...
So, far we haven't got this working, where will this stop?
It stops when you fix all the syntax errors. In this sense, Verilog is no different from any software language (C, Python, etc.). There are strict syntax rules that must be followed; in the case of Verilog, these rules are set by the IEEE Std 1800-2023.
The first error line I see when I run iverilog
is:
2'b11: registers[3] = registers[0];
The 2 lines that follow are the problem. Based on how you indented it, I assume the 3 lines are meant to be together. If that is the case, you can group them with the begin/end
keywords:
2'b11: begin
registers[3] = registers[0];
registers[0] = registers[sig[4:5]];
enable = 1'b1;
end
Unfortunately, simulators don't always provide very helpful error messages. You can also try your code on EDA Playground; it has different simulators which might provide more helpful messages.
There are more errors, but you just need to address each of them one at a time. After you fix all the errors and warnings, there will still be issues with this code that the simulator will not tell you about. In addition to following the rules of syntax, there are good coding practices which must also be followed. For example, this sensitivity list is incomplete:
always @ (enable) begin
The simulation will not work the way you expect it to. A better way to code it is:
always @* begin
begin
-end
pair. \$\endgroup\$