[libre-riscv-dev] Migen Conversions and Update
Daniel Benusovich
flyingmonkeys1996 at gmail.com
Wed Jan 2 05:13:56 GMT 2019
Good evening!
I have been silent for while but not in vain! I have gotten a much better
hold on Verilog, Python, and Migen in the past couple months. An arduous
task indeed as I have never used Verilog before and very sparingly Python.
Anyways I have done my best to port over Jacob's ALU first as a test run. I
have attached the files (I know the mailing list wont have them but I will
put in some choice snippets for the curious bits).
I found that Migen does its best to keep things clean when converting from
python to verilog and while some conversion are perfect the syntax can be a
bit odd.
For example, the ternary operation ( a ? b : c) is replicated via a
function Mux(a, b, c) which I found quite odd as that is not mentioned
anywhere. I only found out after converting it over in despair.
The bigger problem is that I have not yet found a way to convert functions
from python to verilog. The functions are executed (in python) and the
result is then converted into verilog.
Example.py
> def add(a,b):
> return a + b
>
> //Various garbage here
> ...
> a.eq(add(0,1))
> //More various garbage here
> ...
>
> results in
> Example.v
> assign a = 1
>
which was not my dream! Functionality is provided to get around it but it
is not nearly as pretty.
A snippet from the code is as follow
cpu_alu.py
> Case(funct3, {
> 0: result.eq(add_sub_result),
> 1: result.eq(shift_left_result),
> 2: result.eq(lt_result),
> 3: result.eq(lt_result),
> 4: result.eq(xor_result),
> 5: result.eq(shift_right_result),
> 6: result.eq(or_result),
> 7: result.eq(and_result),
> "default": result.eq(0xFFFFFFFF),
> })
>
cpu_alu.v
> always @(*) begin
> result <= 32'd0;
> case (funct3)
> 1'd0: begin
> result <= add_sub_result;
> end
> 1'd1: begin
> result <= shift_left_result;
> end
> 2'd2: begin
> result <= lt_result;
> end
> 2'd3: begin
> result <= lt_result;
> end
> 3'd4: begin
> result <= xor_result;
> end
> 3'd5: begin
> result <= shift_right_result;
> end
> 3'd6: begin
> result <= or_result;
> end
> 3'd7: begin
> result <= and_result;
> end
> default: begin
> result <= 32'd4294967295;
> end
> endcase
> end
>
This physically hurt me as Jacob's function was much prettier to look at
(in Verilog). It seems to be hard without breaking into additional modules
(which is fine but I wanted to keep it to the same file count). In
addition, i have not discovered a way to convert 'X' through as a default
value (forgive my ignorance) if it is possible at all.
A couple nice things after all the bad is no need to declare inputs or
outputs! It is all nicely handled which is a nice change of pace. After
creating a module it can be easily referenced like any python object which
is also very helpful as referencing internal signals and wires is a breeze.
I will continue to work on the conversion unless something else comes up.
Do let me know if anything needs to be done coding: the instructions,
scoreboard, or implementation of Tomusulo's algorithm you are talking about
in the mailing list and google discussion. If you could send me some
references I would be happy to take a jab it.
Happy new year!
Daniel Benusovich
More information about the libre-riscv-dev
mailing list