1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-02-02 14:50:52 +00:00

Moon Patrol Cleanup

This commit is contained in:
Marcel
2024-03-01 17:08:19 +01:00
parent 543d4c00cd
commit e2343a11c4
80 changed files with 5024 additions and 5218 deletions

310
common/CPU/T80/k580vi53.v Normal file
View File

@@ -0,0 +1,310 @@
//
// K580VI53 timer implementation
//
// Copyright (c) 2016 Sorgelig
//
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This source file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// altera message_off 10240
`default_nettype none
module k580vi53
(
// CPU bus
input reset,
input clk_sys,
input [1:0] addr,
input [7:0] din,
output [7:0] dout,
input wr,
input rd,
// Timer signals
input [2:0] clk_timer,
input [2:0] gate,
output [2:0] out,
output [2:0] sound_active
);
wire [7:0] dout0;
wire [7:0] dout1;
wire [7:0] dout2;
assign dout = dout0 & dout1 & dout2;
timer t0(reset, clk_sys, clk_timer[0], din, dout0, wr && (addr == 3) && (din[7:6] == 0), wr && (addr == 0), rd && (addr == 0), gate[0], out[0], sound_active[0]);
timer t1(reset, clk_sys, clk_timer[1], din, dout1, wr && (addr == 3) && (din[7:6] == 1), wr && (addr == 1), rd && (addr == 1), gate[1], out[1], sound_active[1]);
timer t2(reset, clk_sys, clk_timer[2], din, dout2, wr && (addr == 3) && (din[7:6] == 2), wr && (addr == 2), rd && (addr == 2), gate[2], out[2], sound_active[2]);
endmodule
module timer
(
input reset,
input clk_sys,
input clk_timer,
input [7:0] din,
output [7:0] dout,
input wr_cw,
input wr,
input rd,
input gate,
output reg out,
output reg sound_active
);
reg [7:0] q;
reg [7:0] cw;
reg [15:0] counter;
reg [15:0] ld_count;
reg [7:0] load;
reg pause;
reg stop1;
assign dout = q;
always @(posedge clk_sys) begin
reg [15:0] l_counter;
reg msbw, msbr; // according to Siemens doc, read and write have indepenent msb flag.
reg latched;
reg old_wr_cw, old_wr, old_rd;
old_wr_cw <= wr_cw;
old_wr <= wr;
old_rd <= rd;
if(!old_wr_cw && wr_cw) begin
msbw <=0;
msbr <=0;
if(!din[5:4]) begin
if(!latched) begin
latched <=1;
l_counter <= counter;
end
end else begin
cw <= din;
latched <=0;
stop1 <=1;
pause<=1;
end
end
if(!old_wr && wr) begin
case(cw[5:4])
1: begin // high speed mode
ld_count[7:0] <= check(din);
ld_count[15:8] <= 0;
stop1 <=0;
load <=load + 1'd1;
pause <=0;
end
2: begin // low precision mode
ld_count[7:0] <= 0;
ld_count[15:8] <= check(din);
stop1 <=0;
load <=load + 1'd1;
pause <=0;
end
default: begin // full mode
if(msbw) ld_count[15:8] <= check(din);
else ld_count[7:0] <= check(din);
msbw <= ~msbw;
pause <= ~msbw;
if(msbw) begin
stop1 <=0;
load <=load + 1'd1;
end
end
endcase
end
if(!old_rd && rd) begin
casex({latched, msbr, cw[5:4]})
4'b0X01: q <=counter[7:0];
4'b0X10: q <=counter[15:8];
4'b0011: q <=counter[7:0];
4'b0111: q <=counter[15:8];
4'b1X01: begin q <=l_counter[7:0]; latched <=0; end
4'b1X10: begin q <=l_counter[15:8]; latched <=0; end
4'b1011: q <=l_counter[7:0];
4'b1111: begin q <=l_counter[15:8]; latched <=0; end
endcase
msbr <= ~msbr;
end
if(!rd || reset) q <= 255;
if(reset) begin
stop1 <=1;
ld_count <=0;
cw <= 0;
end
end
function [15:0] minus1;
input [15:0] value;
begin
if(!cw[0]) minus1 = value-1'd1;
else begin
minus1 = value;
if(!minus1[3:0]) begin
minus1[3:0] = 9;
if(!minus1[7:4]) begin
minus1[7:4] = 9;
if(!minus1[11:8]) begin
minus1[11:8] = 9;
if(!minus1[15:12]) begin
minus1[15:12] = 9;
end else minus1[15:12] = minus1[15:12]-1'd1;
end else minus1[11:8] = minus1[11:8]-1'd1;
end else minus1[7:4] = minus1[7:4]-1'd1;
end else minus1[3:0] = minus1[3:0]-1'd1;
end
end
endfunction
function [7:0] check;
input [7:0] value;
begin
if(!cw[0]) check = value;
else begin
check[3:0] = (value[3:0]>9) ? 4'd9 : value[3:0];
check[7:4] = (value[7:4]>9) ? 4'd9 : value[7:4];
end;
end
endfunction
reg stop2;
wire stop = stop1 | stop2;
//
// With bugs implemented:
//
// M0,M1,M4,M5 - counter doesn't stop at the end but wrap around instead.
//
// M1,M5 - setting of Control Word doesn't reset counter.
// Counter continue to count old value after ccounter register is set.
//
always @(posedge clk_sys) begin
reg [7:0] old_load;
reg old_gate;
reg start, count_en, m3state;
reg [7:0] stop_delay;
reg old_clk;
// cannot treat it as clock enable because timer clock
// can be fed from output of other timer
old_clk <= clk_timer;
if(old_clk & ~clk_timer) begin
stop2 <= stop1;
old_load <= load;
old_gate <= gate;
start <= stop;
// Assume sound is generated by mode 3 and mode 0(DAC emulation).
sound_active <= (!cw[3:1] || (cw[2:1] == 2'b11)) && !stop;
casex(cw[3:1])
3'b000: if(stop) begin out <=0; count_en <=0; end
else begin
if(start || (old_load != load)) begin
counter <= ld_count;
out <=0;
count_en <=1;
end else if(!pause && gate) begin
counter <= minus1(counter);
if(counter == 1) begin
out <=1;
count_en <=0;
end
end
end
3'b001: if(stop) begin out <=1; count_en <=0; end
else begin
if(!old_gate & gate) begin
counter <= ld_count;
out <=0;
count_en <=1;
end else begin
counter <= minus1(counter);
if((counter == 1) && count_en) begin
out <=1;
count_en <=0;
end
end
end
3'bX10: if(stop || !gate) out <=1;
else begin
if(start || (!old_gate & gate) || (counter <= 1)) begin
counter <=ld_count;
out <=1;
end else begin
counter <= minus1(counter);
if(counter == 2) out <=0;
end
end
3'bX11: if(stop || !gate) begin out <=1; m3state <=1; end
else begin
if(start || (!old_gate & gate) || (counter <= 2)) begin
counter <=ld_count;
out <= m3state;
m3state <= ~m3state;
end else begin
counter <= !counter[0] ? minus1(minus1(counter)) : out ? minus1(counter) : minus1(minus1(minus1(counter)));
end
end
3'b100: if(stop) begin out <=1; count_en <=0; end
else begin
out <=1;
if(start) begin
counter <=ld_count;
count_en <=1;
end else if(gate) begin
counter <= minus1(counter);
if((counter == 1) && count_en) begin
out <=0;
count_en <=0;
end
end
end
3'b101: if(stop) begin out <=1; count_en <=0; end
else begin
out <=1;
if(!old_gate & gate) begin
counter <=ld_count;
out <=1;
count_en <=1;
end else begin
counter <= minus1(counter);
if((counter == 1) && count_en) begin
out <=0;
count_en <=0;
end
end
end
endcase
end
end
endmodule

225
common/IO/A6532.vhd Normal file
View File

@@ -0,0 +1,225 @@
-- A6532 RAM-I/O-Timer (RIOT)
-- Copyright 2006, 2010 Retromaster
--
-- This file is part of A2601.
--
-- A2601 is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License,
-- or any later version.
--
-- A2601 is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with A2601. If not, see <http://www.gnu.org/licenses/>.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity ramx8 is
generic(addr_width : integer := 7);
port(clk: in std_logic;
r: in std_logic;
d_in: in std_logic_vector(7 downto 0);
d_out: out std_logic_vector(7 downto 0);
a: in std_logic_vector(addr_width - 1 downto 0));
end ramx8;
architecture arch of ramx8 is
type ram_type is array (0 to 2**addr_width - 1) of
std_logic_vector(7 downto 0);
signal ram: ram_type;
begin
process (clk, r, a)
begin
if (clk'event and clk = '1') then
if (r = '1') then
d_out <= ram(to_integer(unsigned(a)));
else
ram(to_integer(unsigned(a))) <= d_in;
end if;
end if;
end process;
end arch;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity A6532 is
port(clk: in std_logic;
ph2_en: in std_logic;
r: in std_logic;
rs: in std_logic;
cs: in std_logic;
irq: out std_logic;
d: inout std_logic_vector(7 downto 0) := "ZZZZZZZZ";
pa: inout std_logic_vector(7 downto 0);
pb: inout std_logic_vector(7 downto 0);
pa7: in std_logic;
a: in std_logic_vector(6 downto 0));
end A6532;
architecture arch of A6532 is
signal pa_reg: std_logic_vector(7 downto 0) := "00000000";
signal pb_reg: std_logic_vector(7 downto 0) := "00000000";
signal pa_ddr: std_logic_vector(7 downto 0) := "00000000";
signal pb_ddr: std_logic_vector(7 downto 0) := "00000000";
signal pa_in: std_logic_vector(7 downto 0);
signal pb_in: std_logic_vector(7 downto 0);
signal timer: std_logic_vector(7 downto 0) := "00000000";
signal timer_write: std_logic;
signal timer_read: std_logic;
signal timer_intr: std_logic := '0';
signal timer_intvl: std_logic_vector(1 downto 0) := "11";
signal timer_dvdr: std_logic_vector(10 downto 0) := "00000000001";
signal timer_inc: std_logic;
signal timer_irq_en: std_logic := '0';
signal edge_pol: std_logic := '0';
signal edge_irq_en: std_logic := '0';
signal edge_intr_lo: std_logic := '0';
signal edge_intr_hi: std_logic := '0';
signal edge_intr: std_logic;
signal intr_read: std_logic;
signal ram_d_out: std_logic_vector(7 downto 0);
signal ram_r: std_logic;
begin
io: for i in 0 to 7 generate
-- TEMPORARY FIX
pa(i) <= pa_reg(i) when pa_ddr(i) = '1' else 'Z';
pb(i) <= pb_reg(i) when pb_ddr(i) = '1' else 'Z';
--pa(i) <= 'Z';
--pb(i) <= 'Z';
pa_in(i) <= pa(i);
pb_in(i) <= pb(i) when pb_ddr(i) = '0' else pb_reg(i);
end generate;
ram: work.ramx8 port map(clk, ram_r, d, ram_d_out, a);
ram_r <= (not rs and r) or rs or not cs;
timer_write <= (not r) and rs and a(2) and a(4) and cs;
timer_read <= r and rs and a(2) and (not a(0)) and cs;
intr_read <= r and rs and a(0) and a(2) and cs;
irq <= not ((timer_intr and timer_irq_en) or (edge_intr and edge_irq_en));
edge_intr <= edge_intr_lo when edge_pol = '0' else edge_intr_hi;
process(clk, ph2_en, cs, r, rs, a, ram_d_out, pa_in, pa_ddr, pb_in, pb_ddr, timer, timer_intr, edge_intr)
begin
if r = '1' then
if (cs = '0') then
d <= "ZZZZZZZZ";
elsif rs = '0' then
d <= ram_d_out;
elsif a(2) = '0' then
case a(1 downto 0) is
when "00" =>
d <= pa_in;
when "01" =>
d <= pa_ddr;
when "10" =>
d <= pb_in;
when "11" =>
d <= pb_ddr;
when others =>
null;
end case;
elsif a(0) = '0' then
d <= timer;
elsif a(0) = '1' then
d <= timer_intr & edge_intr & "000000";
else
d <= "--------";
end if;
else
d <= "ZZZZZZZZ";
if (clk'event and clk = '1' and cs = '1' and ph2_en = '1') then
if (rs = '1') then
if a(2) = '0' then
case a(1 downto 0) is
when "00" =>
--pa_reg <= d;
when "01" =>
pa_ddr <= d;
when "10" =>
pb_reg <= d;
when "11" =>
pb_ddr <= d;
when others =>
null;
end case;
elsif a(4) = '0' then
edge_pol <= a(0);
edge_irq_en <= a(1);
end if;
end if;
end if;
end if;
end process;
process(pa7, intr_read)
begin
if (intr_read = '1') then
edge_intr_lo <= '0';
elsif (pa7'event and pa7 = '1') then
edge_intr_lo <= '1';
end if;
if (intr_read = '1') then
edge_intr_hi <= '0';
elsif (pa7'event and pa7 = '0') then
edge_intr_hi <= '1';
end if;
end process;
with timer_intvl select timer_inc <=
timer_dvdr(0) when "00",
timer_dvdr(3) when "01",
timer_dvdr(6) when "10",
timer_dvdr(10) when "11",
'-' when others;
process(clk, ph2_en)
begin
if (clk'event and clk = '1' and ph2_en = '1') then
if (timer_inc = '1') then
timer_dvdr <= "00000000001";
else
timer_dvdr <= timer_dvdr + 1;
end if;
if (timer_write = '1') then
timer <= d - 1;
timer_intvl <= a(1 downto 0);
timer_irq_en <= a(3);
timer_dvdr <= "00000000001";
elsif (timer_intr = '0') then
timer <= timer - timer_inc;
elsif (not (timer = X"00")) then
timer <= timer - 1;
end if;
if (timer = X"00" and timer_inc = '1' and timer_intr = '0' and timer_write = '0') then
timer_intr <= '1';
elsif (timer_read = '1' or timer_write = '1') then
timer_intr <= '0';
end if;
end if;
end process;
end arch;

View File

@@ -0,0 +1,512 @@
FFF4
FFF8
FFFE
0004
000B
0010
0012
0010
000A
0001
FFF5
FFE9
FFE0
FFDD
FFE2
FFF0
0004
001C
0032
0040
0041
0033
0015
FFED
FFC2
FF9E
FF8C
FF91
FFB2
FFEC
0033
007A
00B0
00C5
00AE
006B
0004
FF8D
FF1E
FED2
FEC2
FEFA
FF79
002A
00EF
019B
0204
0205
018C
009F
FF5E
FE03
FCD7
FC29
FC3F
FD48
FF51
0240
05D2
09A8
0D4E
1050
124B
12FB
124B
1050
0D4E
09A8
05D2
0240
FF51
FD48
FC3F
FC29
FCD7
FE03
FF5E
009F
018C
0205
0204
019B
00EF
002A
FF79
FEFA
FEC2
FED2
FF1E
FF8D
0004
006B
00AE
00C5
00B0
007A
0033
FFEC
FFB2
FF91
FF8C
FF9E
FFC2
FFED
0015
0033
0041
0040
0032
001C
0004
FFF0
FFE2
FFDD
FFE0
FFE9
FFF5
0001
000A
0010
0012
0010
000B
0004
FFFE
FFF8
FFF4
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000

View File

@@ -0,0 +1,3 @@
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "jtframe_dcrm.v"]
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "jtframe_fir.v"]
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "jtframe_jt49_filters.v"]

View File

@@ -0,0 +1,69 @@
/* This file is part of JT49.
JT49 is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
JT49 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with JT49. If not, see <http://www.gnu.org/licenses/>.
Author: Jose Tejada Gomez. Twitter: @topapate
Version: 1.0
Date: 25-11-2020
*/
// This is pretty much a copy of jt49_dcrm2
// DC removal filter
// input is unsigned
// output is signed
module jtframe_dcrm #(parameter
SW = 8,
SIGNED_INPUT = 0
)(
input rst,
input clk,
input sample,
input [SW-1:0] din,
output signed [SW-1:0] dout
);
localparam DW=10; // width of the decimal portion
reg signed [SW+DW:0] integ, exact, error;
//reg signed [2*(9+DW)-1:0] mult;
// wire signed [SW+DW:0] plus1 = { {SW+DW{1'b0}},1'b1};
reg signed [SW:0] pre_dout;
// reg signed [SW+DW:0] dout_ext;
reg signed [SW:0] q;
always @(*) begin
exact = integ+error;
q = exact[SW+DW:DW];
pre_dout = { SIGNED_INPUT ? din[SW-1] : 1'b0, din } - q;
//dout_ext = { pre_dout, {DW{1'b0}} };
//mult = dout_ext;
end
assign dout = pre_dout[SW-1:0];
always @(posedge clk)
if( rst ) begin
integ <= {SW+DW+1{1'b0}};
error <= {SW+DW+1{1'b0}};
end else if( sample ) begin
/* verilator lint_off WIDTH */
integ <= integ + pre_dout; //mult[SW+DW*2:DW];
/* verilator lint_on WIDTH */
error <= exact-{q, {DW{1'b0}}};
end
endmodule

View File

@@ -0,0 +1,106 @@
/* This file is part of JTFRAME.
JTFRAME program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
JTFRAME program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with JTFRAME. If not, see <http://www.gnu.org/licenses/>.
Author: Jose Tejada Gomez. Twitter: @topapate
Version: 1.0
Date: 22-11-2020
*/
// Generic FIR filter for stereo signals
// Max 127 coefficients
// Parameters
// KMAX = number of coefficients (8 bit value)
// COEFFS = hex file with filter coefficients
module jtframe_fir(
input rst,
input clk,
input sample,
input signed [15:0] l_in,
input signed [15:0] r_in,
output reg signed [15:0] l_out,
output reg signed [15:0] r_out
);
parameter [6:0] KMAX = 7'd68;
parameter COEFFS = "filter.hex";
reg signed [15:0] ram[0:511]; // dual port RAM
reg [6:0] pt_wr, pt_rd, cnt;
reg st;
reg signed [35:0] acc_l, acc_r;
reg signed [15:0] coeff;
reg signed [31:0] p_l, p_r;
function signed [35:0] ext;
input signed [31:0] p;
ext = { {4{p[31]}}, p };
endfunction
function [6:0] loop_inc;
input [6:0] s;
loop_inc = s == KMAX-7'd1 ? 7'd0 : s+7'd1;
endfunction
function signed [15:0] sat;
input [35:0] a;
sat = a[35:30] == {6{a[29]}} ? a[29:14] : { a[35], {15{~a[35]}} };
endfunction
always@(posedge clk, posedge rst) begin
if( rst ) begin
l_out <= 16'd0;
r_out <= 16'd0;
pt_rd <= 7'd0;
pt_wr <= 7'd0;
cnt <= 7'd0;
acc_l <= 36'd0;
acc_r <= 36'd0;
p_l <= 32'd0;
p_r <= 32'd0;
end else begin
if( sample ) begin
pt_rd <= pt_wr;
cnt <= 0;
ram[ { 2'd1, pt_wr } ] <= l_in;
ram[ { 2'd2, pt_wr } ] <= r_in;
pt_wr <= loop_inc( pt_wr );
acc_l <= 36'd0;
acc_r <= 36'd0;
p_l <= 32'd0;
p_r <= 32'd0;
st <= 0;
end else begin
if( cnt < KMAX ) begin
st <= ~st;
if( st == 0 ) begin
coeff <= ram[ {2'd0, cnt } ];
end else begin
p_l <= ram[ {2'd1, pt_rd } ] * coeff;
p_r <= ram[ {2'd2, pt_rd } ] * coeff;
acc_l <= acc_l + ext(p_l);
acc_r <= acc_r + ext(p_r);
cnt <= cnt+7'd1;
pt_rd <= loop_inc( pt_rd );
end
end else begin
l_out <= sat(acc_l);
r_out <= sat(acc_r);
end
end
end
end
initial begin
$readmemh( COEFFS, ram );
end
endmodule

View File

@@ -0,0 +1,60 @@
/* This file is part of JTFRAME.
JTFRAME program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
JTFRAME program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with JTFRAME. If not, see <http://www.gnu.org/licenses/>.
Author: Jose Tejada Gomez. Twitter: @topapate
Version: 1.0
Date: 25-11-2020
*/
module jtframe_jt49_filters(
input rst,
input clk,
input [ 9:0] din0,
input [ 9:0] din1,
input [ 9:0] din2,
input sample,
output signed [15:0] dout
);
localparam W=11,WD=16-W;
wire signed [W-1:0] dcrm_snd;
reg [W-1:0] base_snd;
wire signed [ 15:0] dcrm16 = { dcrm_snd, dcrm_snd[W-2:W-WD-1] };
//assign dout = dcrm16;
always @(posedge clk, posedge rst ) begin
if( rst ) begin
base_snd <= {W{1'd0}};
end else if(sample) begin
base_snd <= { {W-10{1'b0}}, din0} + { {W-10{1'b0}}, din1} + { {W-10{1'b0}}, din2};
end
end
jtframe_dcrm #(.SW(W)) u_dcrm(
.rst ( rst ),
.clk ( clk ),
.sample ( sample ),
.din ( base_snd ),
.dout ( dcrm_snd )
);
jtframe_fir #(.KMAX(126),.COEFFS("firjt49.hex")) u_fir(
.rst ( rst ),
.clk ( clk ),
.sample ( sample ),
.l_in ( dcrm16 ),
.r_in ( 16'd0 ),
.l_out ( dout ),
.r_out ( )
);
endmodule