spr: Cleanup decoding of SPR numbers

Use a function to obtain the integer number and use constants
with the architected numbers. Replace std_match with a case
statement.

This also has the side effect of returning 0 instead of some
random previous result on mfspr of an unknown SPR.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
pull/120/head
Benjamin Herrenschmidt 5 years ago
parent cff4b13a9b
commit 83a8bb0238

@ -1,10 +1,21 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library work;
use work.decode_types.all;

package common is

-- SPR numbers
subtype spr_num_t is integer range 0 to 1023;

function decode_spr_num(insn: std_ulogic_vector(31 downto 0)) return spr_num_t;

constant SPR_LR : spr_num_t := 8;
constant SPR_CTR : spr_num_t := 9;
constant SPR_TB : spr_num_t := 268;

type ctrl_t is record
lr: std_ulogic_vector(63 downto 0);
ctr: std_ulogic_vector(63 downto 0);
@ -216,4 +227,8 @@ package common is
end common;

package body common is
function decode_spr_num(insn: std_ulogic_vector(31 downto 0)) return spr_num_t is
begin
return to_integer(unsigned(insn(15 downto 11) & insn(20 downto 16)));
end;
end common;

@ -269,16 +269,17 @@ begin
v.e.write_cr_data(hi downto lo) := newcrf;
end loop;
when OP_MFSPR =>
if std_match(e_in.insn(20 downto 11), "0100100000") then
case decode_spr_num(e_in.insn) is
when SPR_CTR =>
result := ctrl.ctr;
result_en := '1';
elsif std_match(e_in.insn(20 downto 11), "0100000000") then
when SPR_LR =>
result := ctrl.lr;
result_en := '1';
elsif std_match(e_in.insn(20 downto 11), "0110001000") then
when SPR_TB =>
result := ctrl.tb;
result_en := '1';
end if;
when others =>
result := (others => '0');
end case;
result_en := '1';
when OP_MFCR =>
if e_in.insn(20) = '0' then
-- mfcr
@ -308,11 +309,13 @@ begin
end if;
v.e.write_cr_data := e_in.read_data3(31 downto 0);
when OP_MTSPR =>
if std_match(e_in.insn(20 downto 11), "0100100000") then
case decode_spr_num(e_in.insn) is
when SPR_CTR =>
ctrl_tmp.ctr <= e_in.read_data3;
elsif std_match(e_in.insn(20 downto 11), "0100000000") then
when SPR_LR =>
ctrl_tmp.lr <= e_in.read_data3;
end if;
when others =>
end case;
when OP_POPCNTB =>
result := ppc_popcntb(e_in.read_data3);
result_en := '1';

Loading…
Cancel
Save